hdu 2602 Bone Collector

来源:互联网 发布:重采样 算法 编辑:程序博客网 时间:2024/04/26 03:26

经典的0-1背包问题,发现自己的一个毛病,不够细心。我原本觉得用简单的dp可以做,即dp[i][j]表示前i个物品,背包容量为j的最大值。状态转移方程为:if(j>=w[i])  dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])。其实没有考虑到j<w[i]的情况。j<w[i]时,dp[i][j]=dp[i-1][j]。所以应改成if(j>=w[i]&&dp[i-1][j-w[i]]+v[i]>dp[i-1][j]) dp[i][j]=dp[i-1][j-w[i]]+v[i]; else dp[i][j]=dp[i-1][j]; 另外,遍历时应是从i=1-->n个物品,j=0-->v,而不是j=w[1]-->v,因为w[1]可能很大,这样很多值未被计算到。

AC代码:

//freopen("input.txt",  "r", stdin);  //输入太多太麻烦时,从文本中读数据//freopen("output.txt", "w", stdout); //注释掉此句则输出到控制台#include<stdio.h>#define NUM 1005int dp[NUM][NUM]={0};int value[NUM],weight[NUM];int max(int a,int b){return a>b?a:b;}int main(){int t,n,v,i,j;//freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);scanf("%d",&t);while(t--){scanf("%d%d",&n,&v);for( i=1;i<=n;i++){scanf("%d",&value[i]);}for(j=1;j<=n;j++){scanf("%d",&weight[j]);}//dp[1][weight[1]]=value[1];for(i=1;i<=n;i++){for(j=0;j<=v;j++){if(j>=weight[i]&&dp[i-1][j-weight[i]]+value[i]>dp[i-1][j])dp[i][j]=dp[i-1][j-weight[i]]+value[i];else dp[i][j]=dp[i-1][j];}}printf("%d\n",dp[n][v]);}return 0;}