HDU 2602Bone Collector 01背包问题
题意:给出一个t代表有t组数据,然后给出n,n代表有n种石头,v代表旅行者的背包容量,然后给出n种石头的价值和容量大小,求能带走的最大价值
思路:01背包问题,每种石头只有拿与不拿两种状态、(其实我是为理解dp而来的)
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 const int qq=1000+10; //开始数值写小了 只写了100+10 6 int value[qq]; 7 int weight[qq]; 8 int dp[qq][qq]; 9 void kill(int n,int v) 10 { 11 for(int i=0;i<=n;++i) 12 dp[0][i]=dp[i][0]=0; 13 for(int j,i=1;i<=n;++i) 14 for(j=0;j<=v;++j) 15 if(j<weight[i]) 16 dp[i][j]=dp[i-1][j]; 17 else if(dp[i-1][j-weight[i]]+value[i]>dp[i-1][j]) 18 dp[i][j]=dp[i-1][j-weight[i]]+value[i]; 19 else 20 dp[i][j]=dp[i-1][j]; 21 } 22 int main() 23 { 24 int t,n,v; 25 scanf("%d",&t); 26 while(t--){ 27 scanf("%d%d",&n,&v); 28 for(int i=1;i<=n;++i) 29 scanf("%d",&value[i]); 30 for(int j=1;j<=n;++j) 31 scanf("%d",&weight[j]); 32 kill(n,v); 33 printf("%d\n",dp[n][v]); 34 } 35 }
一维数组也能过、只是第二层必须反序来、顺序的话同一件物品可能会被取多次
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 const int qq=1050; 8 int w[qq],v[qq]; 9 int dp[qq]; 10 int main() 11 { 12 int t; 13 scanf("%d",&t); 14 while(t--){ 15 int n,m; 16 memset(dp,0,sizeof(dp)); 17 scanf("%d%d",&n,&m); 18 for(int i=1;i<=n;++i) 19 scanf("%d",&v[i]); 20 for(int i=1;i<=n;++i) 21 scanf("%d",&w[i]); 22 for(int i=1;i<=n;++i) 23 for(int j=m;j>=v[i];--j) //一定记得是逆序、可以自己模拟一遍 24 dp[j]=max(dp[j],dp[j-w[i]]+v[i]);; 25 printf("%d\n",dp[m]); 26 } 27 return 0; 28 }
贴一份WA的代码
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 const int qq=1050; 8 int w[qq],v[qq]; 9 int dp[qq][qq]; 10 int main() 11 { 12 int t; 13 scanf("%d",&t); 14 while(t--){ 15 int n,m; 16 memset(dp,0,sizeof(dp)); 17 scanf("%d%d",&n,&m); 18 for(int i=1;i<=n;++i) 19 scanf("%d",&v[i]); 20 for(int i=1;i<=n;++i) 21 scanf("%d",&w[i]); 22 for(int i=1;i<=n;++i) 23 for(int j=w[i];j<=m;++j) //我开始还在想为什么这样不对 24 dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]); 25 printf("%d\n",dp[n][m]); 26 } 27 return 0; 28 } 29 //先出一组数据吧、 30 /* 1 31 5 0 32 2 4 1 5 1 33 0 0 1 0 0 34 这样的话在dp[3]的话是根本不会进入到第二层循环的、 35 也就是说dp[3][0]的值为0 36 */