HDU2602-01背包基础

Question:

输入:首先输入测试用例的个数
其次一次输入物品的个数N和背包容量V
随后输入的n个数代表每个物品价值
最后的输入的n个数代表每个物品的体积

要求输出背包最多可以携带多大价值的物品

Solution1:

01背包的思想:
定义状态:
DP[i][j]:代表在背包的容量为j的情况下,在取第i个物品的时候,我们最大可以携带的物品的总价值

状态转移方程:
if  j>volume[i](代表目前的容量可以装进去)   DP[i][j]=max(DP[i-1][j],DP[i-1][j-volume[i]]+value[i])
else DP[i][j]=DP[i-1][j](代表如果目前装不进去物品i,那么我们的最大容量和上一级相同)

PS:本题需要注意,因为本题中的物品可能会存在体积为0的情况,这时候我们是无条件会选择装填的,小心着个用例就好

Code1:

#include"iostream"
#include"cstdio"
#include"cstring"
#include"math.h"
#define N 1005

using namespace std;

int t;
int n,v;
int dp[N][N];
int value[N];
int volume[N];

int maxp(int x,int y)
{
    if(x>y) return x;
    else return y;
}

int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>v;
        for(int i=1;i<=n;i++) cin>>value[i];
        for(int i=1;i<=n;i++) cin>>volume[i];
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=v;j++)
            {
                if(j>=volume[i]) dp[i][j]=maxp(dp[i-1][j],dp[i-1][j-volume[i]]+value[i]);
                else dp[i][j]=dp[i-1][j];
            }
        }
        cout<<dp[n][v]<<endl;
    }
    return 0;
}

Solution2:

同为背包的思想,但是我们在进行背包的思路步骤的同时我们会发现,我们开辟的背包是二维的,但是我们的数组再从物品1耿总导物品n的过程中会发现,我们本级的总价值相对于相对于上一级是会只增不减的,那么这就意味着,我们对于该二维DP是可以优化的,也就是说,我们完全可以用以为的DP数组来公董模拟二维的数组的情况,大大的优化我们的空间复杂度
另外,我们在进行计算的时候没必要对背包的容量从0开始跑到最大容量V,我们直接从volume[i]开始跑就可以了,因为在volume[i]之前我们始终是跟从上一级的背包价值的,只有从volume[i]开始我们才开始更新优化的判断,这样的话,我们还可以优化时间复杂度

最后根据HDU上的实战测试,上一种基本的方法耗时126Ms,而优化之后我们的不仅小号了更少的内存,并且运行时间优化到96Ms

Code2:

#include"iostream"
#include"cstdio"
#include"cstring"
#include"math.h"
#define N 1005

using namespace std;

int t;
int n,v;
int dp[N];
int value[N];
int volume[N];

int maxp(int x,int y)
{
	if(x>y) return x;
	else return y;
}

int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>v;
		for(int i=1;i<=n;i++) cin>>value[i];
		for(int i=1;i<=n;i++) cin>>volume[i];
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)
		{
			for(int j=v;j>=volume[i];j--)
			{
 				if(j>=volume[i]) dp[j]=maxp(dp[j],dp[j-volume[i]]+value[i]);
			}
		}
		cout<<dp[v]<<endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值