https://www.luogu.org/problemnew/show/P1164
开个玩笑,这是一道简单的动规题,定义f[i][j]为用前i道菜用光j元钱的办法总数,其状态转移方程如下:
(1)if(j==第i道菜的价格)f[i][j]=f[i-1][j]+1;
(2)if(j>第i道菜的价格) f[i][j]=f[i-1][j]+f[i-1][j-第i道菜的价格];
(3)if(j<第i道菜的价格) f[i][j]=f[i-1][j];
说的简单一些,这三个方程,每一个都是在吃与不吃之间抉择。若钱充足,办法总数就等于吃这道菜的办法数与不吃这道菜的办法数之和;若不充足,办法总数就只能承袭吃前i-1道菜的办法总数。依次递推,在最后,我们只要输出f[n][m]的值即可。
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int a[101],f[101][10001]={0}; 6 int main() 7 { 8 int n,m; 9 cin>>n>>m; 10 for(int i=1;i<=n;++i)cin>>a[i]; 11 for(int i=1;i<=n;++i) 12 for(int j=1;j<=m;++j) 13 { 14 if(j==a[i])f[i][j]=f[i-1][j]+1; 15 if(j>a[i]) f[i][j]=f[i-1][j]+f[i-1][j-a[i]]; 16 if(j<a[i]) f[i][j]=f[i-1][j]; 17 } 18 cout<<f[n][m]; 19 return 0; 20 }
我的代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 typedef long long ll; 7 int f[50010];//F[i]就是当前方案数,维度中i是花费 8 int main() 9 { 10 int n, m; 11 int a[10010]; 12 cin >> n >> m; 13 for (int i = 1; i <= n; i++) 14 { 15 cin >> a[i]; 16 } 17 f[0] = 1;//f[0]=1的时候就是剩余的钱刚好买完一个菜后用完,是可以用完的情况,所以要+1 18 for (int i = 1; i <= n; i++) 19 { 20 for (int j = m; j >= a[i]; j--) 21 { 22 f[j] = f[j] + f[j - a[i]];//现在的花费+=我不点这个菜的时候的花费 23 } 24 } 25 cout << f[m] << endl; //最后把最后一个点的花费输出来就可以了 26 return 0; 27 }