HDU 2602 Bone Collector【01背包】

HDU 2602 Bone Collector 

大致意思:n个骨头,不同骨头价值和重量不同,知道背包的容量s,求最大价值。

--------------------------------------------------------------------------------------------------------------------------------------------------

动态规划先找出子问题,我们可以这样考虑:在物品比较少,背包容量比较小时怎么解决?用一个数组dp[i][j]表示,在只有i个物品,容量为j的情况下背包问题的最优解,那么当物品种类变大为i+1时,最优解是什么?第i+1个物品可以选择放进背包或者不放进背包,假设放进背包(前提是放得下),那么dp[i+1][j]=dp[i][j-weight[i+1]+value[i+1];

如果不放进背包,那么dp[i+1][j]=dp[i][j]。放不下就是dp[i+1][j]=dp[i][j];

这就得出了状态转移方程:

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

/**01背包**/
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=1010;
int w[maxn];//重量 
int v[maxn];//价值 
int dp[maxn][maxn];
int n,s;
 
void slove()
{
    for(int i = 1; i <= n; i++)
    {
        for(int j = 0; j <= s; j++)
        {
            if(j < w[i])///背包容量比第i个物品的重量小
                dp[i][j]  = dp[i-1][j];
            else
                dp[i][j] =  max(dp[i-1][j], dp[i-1][j - w[i]] + v[i]);
            cout << dp[i][j] << ' ';
        }
        cout << endl;
    }
}
 
int main()
{
    
    int T;
    cin>>T;
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        cin>>n>>s;
        for(int i=1; i<=n; i++)
            cin>>v[i];//价值 
        for(int i=1; i<=n; i++)
            cin>>w[i];//重量
        slove();
        cout << dp[n][s] << endl;
    }
    return 0;
}

 -------------------------------------------------------------------------------------------------------------------------------------------------------------------

上面计算 dp[i][j]可以看出,在计算  dp[i][j]时只使用了 dp[i-1][0……j],没有使用其他子问题,因此在存储子问题的解时,只存储 dp[i-1]子问题的解即可。这样可以用两个一维数组解决,一个存储子问题,一个存储正在解决的子问题。再进一步思考,计算dp[i][j]时只使用了 dp[i-1][0……j],没有使用dp[i-1][j+1]这样的话,我们先计算j的循环时,让j=M……1,只使用一个一维数组即可。这就得出了状态转移方程:

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

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[1010],weight[1010],value[1010];//全局变量,自动清0; 
int main()
{
	int t,n,m,i,j;
	cin>>t;
	while(t--) 
	{
		memset(dp,0,sizeof(dp));//记得清0; 
		cin>>n>>m;
		for(i=1;i<=n;i++)
			cin>>value[i];
		for(i=1;i<=n;i++)
			cin>>weight[i];
		for(i=1;i<=n;i++)
		{
			for(j=m;j>=weight[i];j--)
			{
				dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
			}
		}
		cout<<dp[m]<<endl;
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/tingtingyuan/article/details/81510360