nyoj289苹果--01背包

状态转移方程为:dp[i][j] 表示i件物品放入容量为j的背包中的最大价值

dp[i][j] = max(dp[i-1][j], dp[i-1][j-size[i]]+value[i]);

分析:第i件物品放不放入背包有两种选择:若不放进背包,则dp[i][j]的值等于i-1件物品放进容量为j的背包中的最大价值,即

dp[i][j] = dp[i-1][j],

若放进背包的话, 则dp[i][j]的值等于i-1件物品放进容量为j-size[i]的背包中的最大价值,即

dp[i][j] = dp[i-1][j-size[i]]+value[i] ;



#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1010;
typedef struct Apple
{
	int size,value;
}Apple;
Apple apple[maxn];
int res[maxn][maxn];
int main()
{
	int n,v;
	while(scanf("%d%d",&n,&v)==2 && (n&&v))
	{
		memset(res,0,sizeof(res));
		int sum = 0;
		for(int i=1;i<=n;++i)
		{
			scanf("%d%d",&apple[i].size,&apple[i].value);
		}
		
		for(int i=1;i<=n;++i)
			for(int j=1;j<=v;++j)
				if(apple[i].size<=j)//当背包的空间大于 第i个苹果的大小时 
					res[i][j] = max(res[i-1][j],res[i-1][j-apple[i].size]+apple[i].value);
				else
					res[i][j] = res[i-1][j];//否则,背包空间装不下此苹果,此时的装入苹果的价值 等于 不放入这个苹果的背包内苹果的价值
		printf("%d\n",res[n][v]);
	}
	return 0;
}

上面计算res[i][j]可以看出,在计算res[i][j]时只使用了res[i-1][0……j],
没有使用其他子问题,因此在存储子问题的解时,只存储res[i-1]子问题的解即可。

这样可以将res降成一维数组!!! 


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1010;
typedef struct Apple
{
	int size,value;
}Apple;
Apple apple[maxn];
int res[maxn];
int main()
{
	int n,v;
	while(scanf("%d%d",&n,&v)==2 && (n&&v))
	{
		memset(res,0,sizeof(res));
		int sum = 0;
		for(int i=1;i<=n;++i)
			scanf("%d%d",&apple[i].size,&apple[i].value);
		
		for(int i=1;i<=n;++i)
			for(int j=v;j>=apple[i].size;--j)
					res[j] = max(res[j],res[j-apple[i].size]+apple[i].value);
		printf("%d\n",res[v]);
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/m0_38024592/article/details/80084851