HDU2602-01背包基础

来源:互联网 发布:mysql数据库存储过程 编辑:程序博客网 时间:2024/06/06 11:39

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 1005using 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 1005using 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
原创粉丝点击