首页 > 其他分享 >李白打酒的三种解法

李白打酒的三种解法

时间:2023-10-11 18:33:38浏览次数:22  
标签:std return int 打酒 dp dfs 李白 解法 MOD

题目描述
话说大诗人李白,一生好饮。幸好他从不开车。

一天,他提着酒壶,从家里出来,酒壶中有酒 2 斗。他边走边唱:

无事街上走,提壶去打酒。

逢店加一倍,遇花喝一斗。

这一路上,他一共遇到店 N 次,遇到花 M 次。已知最后一次遇到的是花, 他正好把酒喝光了。

请你计算李白这一路遇到店和花的顺序,有多少种不同的可能?

注意:壶里没酒 ( 0 斗) 时遇店是合法的,加倍后还是没酒;但是没酒时遇花是不合法的。

输入格式
第一行包含两个整数 N 和 M.

输出格式
输出一个整数表示答案。由于答案可能很大,输出模 1000000007 的结果。

样例输入
5 10
样例输出
14
提示
如果我们用 0 代表遇到花,1 代表遇到店,14 种顺序如下:

010101101000000
010110010010000
011000110010000
100010110010000
011001000110000
100011000110000
100100010110000
010110100000100
011001001000100
100011001000100
100100011000100
011010000010100
100100100010100
101000001010100
对于 40% 的评测用例:1 ≤ N, M ≤ 10。
对于 100% 的评测用例:1 ≤ N, M ≤ 100。

 

//法一:dfs暴力,时间复杂度O(2^n)
#include <iostream>

const int MOD = 1e9 + 7;

int dfs(int n, int m, int b) {
    if (!n && !m && !b) {
        return 1;
    }
   //b不能等于0,因为题目要求最后一次要遇到花,所以在此之前酒不能变为0 if (n < 0 || m < 0 || b <= 0 || b > m) { return 0; } return (dfs(n - 1, m, 2 * b) % MOD + dfs(n, m - 1, b - 1) %MOD) %MOD; } int main() { int n, m, b = 2; std::cin >> n >> m; std::cout << dfs(n, m, b) << std::endl; return 0; }
//法二:记忆化搜索:时间复杂度O(n*m^2)
#include <iostream>

const int MOD = 1e9 + 7;
//map用来记录递归到终点的部分字段结果,保存后用来避免重复计算 std::unordered_map<int, std::unordered_map<int, std::unordered_map<int, long long>>> mp; int dfs(int n, int m, int b) { if (mp[n][m].count(b)) { return mp[n][m][b]; } if (n < 0 || m < 0 || b <= 0 || b > m) { return mp[n][m][b] = 0; } return mp[n][m][b] = (dfs(n - 1, m, 2 * b) + dfs(n, m - 1, b - 1)) % MOD; } int main() { int n, m; std::cin >> n >> m; mp[0][0][0] = 1; std::cout << dfs(n, m, 2) << std::endl; return 0; }
//法三:动态规划,时间复杂度O(n*m^2),但是因为没有使用hashmap,少了很多内存分配与查询的开销,速度提高显著
#include <iostream>
const int N = 110;,
const int MOD = 1e9 + 7;

//dp(i, j, k)表示遇到i家店,j次花,拥有k斗酒的路径条数
long long dp[N][N][N];

int main()
{
    int n, m;
    std::cin >> n >> m;
    dp[0][0][2] = 1;
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            for (int k = 0; k <= m - j; k++) {
                if (!(k & 1) && i) {
                    dp[i][j][k] = dp[i - 1][j][k >> 1];
                }
                if (j) {
                    dp[i][j][k] += dp[i][j - 1][k + 1];
                }
                dp[i][j][k] %= MOD;
            }
        }
    }
    std::cout << dp[n][m - 1][1] << std::endl;
    return 0;
}

 

标签:std,return,int,打酒,dp,dfs,李白,解法,MOD
From: https://www.cnblogs.com/whysopt/p/17757899.html

相关文章

  • 2023.9.27 Shui_Dream《一类 NPC 问题的多项式时间解法》
    给出一个字符串\(P\),\(P\)是由小写英文字母构成的。求总共有多少个不同的字符串\(Q\),使得下面两个条件同时成立:字符串\(Q\)非空。字符串连接得到\(QQ\),必须满足\(QQ\)是\(P\)的子序列。因为\(n\le100\)很小所以可以直接枚举第二次出现的首位,DP求这个点两边公......
  • CCF第三十一次计算机软件能力认证202309-1坐标变换(其二) (暴力求解法,80分)
    代码如下此算法是暴力求解算法,时间复杂度O(mn),只能得80分,而且代码在模拟系统里一直提交错误(评判系统应该有bug),但在本地可以正常运行*#include<stdio.h>#include<stdlib.h>#include<math.h>typedefstructOperation{/*操作结点*/inttype;doublevalu......
  • 八大常见类型的行列式及其解法
    本文记录了八大常见类型的行列式及其解法,解法从一般性到特殊性都有,分享给大家,例子都特别经典好用,希望对线代、高代初学者以及考研党有用。类型总览:箭型行列式两三角型行列式两条线型行列式范德蒙德型行列式\(Hessenberg\)型行列式三对角型行列式各行元素和相等型行列式......
  • LeetCode952三部曲之一:解题思路和初级解法(137ms,超39%)
    欢迎访问我的GitHub这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos题目描述难度:困难编程语言:Java给定一个由不同正整数的组成的非空数组nums,考虑下面的图:有nums.length个节点,按从nums[0]到nums[nums.length-1]标记;只有当......
  • 长回文子串-动态规划解法
    题目:​给你一个字符串s,找到s中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。​Golang代码示例​​逻辑视频讲解funclongestPalindrome(sstring)string{ /......
  • 几则组合求和式的积分解法
    记号约定:本文中默认\(n\in\mathbb{N}\),\(k\in\mathbbZ\),隐去范围的求和指标取一切使求和对象有意义且非零的值.【例1】求\[\sum_k{n\choosek}\dfrac1{k+1}.\]【解】注意到\(\displaystyle\intx^k\mathrm{d}x=\dfrac1{k+1}x^{k+1}+C\),于是\[\begin{aligned}\sum_k{n\ch......
  • leetcode 题库994——bfs典型解法(队列+递归实现)
     classSolution:deforangesRotting(self,grid:list[list[int]])->int:m,n=len(grid),len(grid[0])queue,good=[],[]defbfs(queue,good,m,n,grid):times=0directions=[(-1,0),(1,0),(0,1),(0,-1)]......
  • LeetCode题库77.组合——dfs典型解法,递归+回溯+剪枝
     classSolution:defcombine(self,n:int,k:int):nums=[x+1forxinrange(n)]res,ans=[],[]defdfs(nums:list[int]):iflen(ans)==k:ans_copy=ans.copy()#复制,避免ans数组改变使res跟着改变......
  • Luogu P3369 【模板】普通平衡树 01Tire树解法
    题目传送门闲话:Luogu总共105篇题解中只有4篇01Tire树解法,虽说是非正解但未免也太少了些(貌似也不少?)……总之01Tire树的效率并不低,这道题用01Tire是很轻松的。Q:这题为什么可以用01Tire树解?能否解决一个问题,无非于三个点:可行性,空间,时间。本题要求维护一个有序数集,能进行元素修改......
  • 【LeetCode173. 最多连胜的次数】MySQL用户变量编程解法
    目录题目地址题目描述代码题目地址https://leetcode.cn/problems/longest-winning-streak/description/题目描述选手的 连胜数是指连续获胜的次数,且没有被平局或输球中断。编写解决方案来计算每个参赛选手最多的连胜数。结果可以以任何顺序返回。代码WITHt1AS(......