完全背包问题

 题目描述  已知背包总空间s 对于所给的n种物品 每种物品所占空间 w[i] 价值 p[i] 每种物品有无限多个 求在不超过背包容量的前提下 背包所能容纳物品的最大价值或者最小价值


01背包与完全背包的代码上的区别就是 循环在每个物品时 背包体积 的时候的逆序与正序

即 for i=0->n

01背包 for j=s->w[i]   完全背包 for j=w[i]->s  

*对于为什么01背包逆序而完全背包正序 的问题要弄清楚   

01背包由于每件物品只有一个 只存在一种情况 如果正序进行的话 会造成一件物品的重选问题导致问题的矛盾 所以一定要逆序

完全背包 一件物品可以有无限个 故当处理第 i 件物品时 dp[v-wp[i]] 仍可以参考第i件物品拿的少的情况 所以可以正序

完全背包代码如下

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int inf=99999999;
int s,e;
int N;
int dp[10005];
struct coins
{
    int val;
    int weight;
}data[505];
int CompletePack()
{
    for(int i=1;i<=(e-s);i++)
    dp[i]=inf;
    dp[0]=0;
    //一维  O(vn) 
    for(int i=1;i<=N;i++)
    {
        for(int j=data[i].weight;j<=(e-s);j++)
        {
             if(dp[j-data[i].weight]+data[i].val<dp[j])
             dp[j]=dp[j-data[i].weight]+data[i].val;
        }
    }
    
    return 0;
}
int main()
{
    int time;
    scanf("%d",&time);
    while(time--)
    {
        scanf("%d%d%d",&s,&e,&N);
        for(int i=1;i<=N;i++)
           scanf("%d%d",&data[i].val,&data[i].weight);

        CompletePack();

        //If the weight cannot be reached exactly
        if(dp[e-s]!=inf)
        cout<<"The minimum amount of money in the piggy-bank is "<<dp[e-s]<<"."<<endl;
        else
        cout<<"This is impossible."<<endl;
        /*
        for(int i=0;i<=(end-start);i++)
        {
            if(i!=(end-start)) cout<<dp[i]<<" ";
            else
             cout<<dp[i]<<endl;
        }
        */
    }

    return 0;
}

参考题目  http://acm.hdu.edu.cn/showproblem.php?pid=1114

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值