方案数问题.背包.
使用dp[i][j]表示前i道菜刚好能花费完j钱的方案数,压成一维.(dp[j])
那么明显地,dp[0]=1.
对于每个j,花完j钱的方案划分为两种:点了i菜和没点i菜,将这两种情况的方案数加起来,即dp[j] = dp[j] + dp[j - w[i]].(加号左边表示没点i菜,不好理解就还原成二维再想想)
即dp[j] += dp[j - w[i]].
本质上是对于每种菜选还是不选做出判断和统计.
背包问题即选与不选的问题.
再往前推一些,最初学到的解决这种问题的方法是搜索,回溯,这种动态规划与之思想十分相近.
这时候需要看知乎,总会有启发.
#include <algorithm> #include <cstdio> #include <cstring> #include <iostream> using namespace std; int n, m, w[110], dp[10010]; int main(){ cin >> n >> m; for(int i = 0; i < n; i++) cin >> w[i]; for(int i = 0; i < n; i++) for(int j = m; j >= w[i]; j--){ dp[0] = 1; dp[j] += dp[j - w[i]]; } cout << dp[m] << endl; return 0; }