林克的背包
描述
林克拥有一个可扩容的背包,前提是需要有足够的克罗克果实。
林克当前背包的总容积是70。
假设在道具商店里有n种道具,假设每个道具的体积分别是a1,a2……an。
请问,要塞满林克的背包一共有多少种不同方法呢?
输入
输入的第一行是正整数n (1 <= n <= 50),表示不同的道具的数目。
接下来的n行,每行有一个1到70之间的正整数,表示不同道具的体积值a1,a2……an。
输出
输出塞满林克的背包的总方式数。
样例
13
30
28
64
58
9
66
28
63
34
10
27
28
30
2
难度
中等,动态规划
解释
递归方程
如果没有容积放 放法为1
如果没有物品放 放法为0
第j个物品,放法为 当前物品放入背包的方法+不放入背包的方法
递归方程中含有重复计算的子问题,采用动态规划填表法,d[i,j]代表容积为i的背包放j种道具的方法数
递推式: d[i,j] = d[i,j-1] + d[i-道具空间,j]
代码
#include <iostream>
using namespace std;
#define BAGSIZE 70
int bags(int daoju[],int n){
int dp[BAGSIZE+1][n+1];
for(int j=0;j<=BAGSIZE;j++) //表格第一列,道具为0,放法为0
dp[j][0] = 0;
for(int i=0;i<=n;i++) //表格第一行,空间为0,放法为1
dp[0][i] = 1;
for(int i=1;i<=BAGSIZE;i++){
for(int j=1;j<=n;j++){
dp[i][j] = dp[i][j-1];
if(i-daoju[j]>=0)
dp[i][j] += dp[i-daoju[j]][j-1];
}
}
for(int i=0;i<=BAGSIZE;i++){
for(int j=0;j<=n;j++)
cout<<dp[i][j]<<' ';
cout<<endl;
}
return dp[BAGSIZE][n];
}
int main() {
int n;
cin>>n;
int daoju[n+1];
daoju[0] = 0;
for(int i=1;i<=n;i++)
cin>>daoju[i];
cout<<bags(daoju,n);
return 0;
}