码迷,mamicode.com
首页 > 其他好文 > 详细

完全背包

时间:2018-08-17 21:34:42      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:top   状态   完全背包   思考   多少   can   一个   \n   ++i   

处理何种问题:给定 n 种物品(每种类型无限)和一个容量为 V 的背包,物品 i 的体积为 vi,其价 值为 pi,求其最终可以装进背包的物品最大价值。

 

性能:时间复杂度为O(nV)。

 

原理:在学习背包之前,可能是思考方向的不对的原因,导致对背包题解的做法有些误解,现在借着写完全背包我在这里阐述一下我对于背包的理解。

在此,我先假定一个数组dp[V],里面存的是当背包容量只有V的情况下,可以存的物品的最大价值是多少。然后,我们假设只有第一件物品arr[0],然后我们利用arr[0],对dp[V]进行赋值操作,如下图所示:

dp[0]

dp[arr[0].v]

dp[arr[0].v+1]

dp[arr[0].v*2]

dp[V]

0

arr[0].p

arr[0].p

arr[0].p*2

V/arr[0].v*arr[i].p

然后,我在dp[V]已更新的基础上我们再加上一个物品arr[1],对此我们依旧仿照上面的操作判断dp[V]=max(dp[V],dp[V-arr[1].v]+arr[1].p),毕竟我们只需要确保当背包为V时,看看怎么加物品i使得dp[V]最大(是放还是不放),这是一个迭代的过程,dp[V-arr[1].v]+arr[1].p就是为了得到在放该物品之后能得到的最大值。

在捋清思路之后,完全背包的解法就是这么显得顺其自然,很像贪心。

 

实现步骤:与01背包类似,具体看代码。

 

备注:状态转移方程具体看代码,个人觉得与01背包相似,但又有一些根本上的不同,在这里就不写了。

 

输入样例解释

5 1000 //n种物品,背包容量为V

144 990//第0种物品的体积和价值

487 436

210 673

567 58

1056 897

输出样例解释

5940 //最大价值

#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;

struct node
{
    int v,p;
};
node arr[11000];
int dp[100010];

int main()
{
    int n,V;
    memset(dp,0,sizeof(dp));
    scanf("%d%d",&n,&V);

    for(int i=0;i<n;++i)    scanf("%d%d",&arr[i].v,&arr[i].p);

    for(int i=0;i<n;++i)
    {
        for(int j=arr[i].v;j<=V;++j)
        {
            dp[j]=max(dp[j],dp[j-arr[i].v]+arr[i].p);
        }
    }

    printf("%d\n",dp[V]);
    return 0;
}

  

完全背包

标签:top   状态   完全背包   思考   多少   can   一个   \n   ++i   

原文地址:https://www.cnblogs.com/l1l1/p/9495252.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!