hdu 2602 Bone Collector

经典的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 1005
int 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;
}


你可能感兴趣的:(HDU,HDU)