首页 > 其他 > 详细

基础背包题集

时间:2019-04-10 22:10:44      阅读:143      评论:0      收藏:0      [点我收藏+]

HDU 1171  杭电分设备(多重背包)

题意:给一组物品,要求分给A,B 2个人,要求A分到的价值总和不小于B,输出A,B分到的价值总和。

题解:多重背包问题:思路比较简单,设sum为物品的总价值

  方法1:直接打背包价值的表F[V](装满背包初始化为-INF),从v=sum/2往右找,满足F[v]>0的即可; 

  方法2:设背包容量为V=sum/2,直接找F[V]即可;

反思:当价值和容量是同一种的时候,基本都有2种方法,初始化为-INF,找满足条件下的因变量下对于的自变量x(什么样容量的背包可以被装满),

   或初始化为0(这个背包最多可以装下的价值),找因变量;(把背包问题看成函数求最优解,x为定义域(容量),y为值域(价值总和等));

方法1代码:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

const int maxn=2e6+5;
const int INF=0x3f3f3f3f;
int f[maxn], c[maxn], w[maxn];
int main()
{
    //freopen("in.txt", "r", stdin);
    int n;
    while (cin>>n, n>=0)
    {
        int all_n=1, sum=0;
        while(n--)
        {
            int val,num,k; cin>>val>>num;
            sum=sum+val*num;
            for(k=1; k<num; k<<=1){
                w[all_n++]=k*val;
                num=num-k;
            }
            if(num)
                w[all_n++]=num*val;
        }
        for(int v=0; v<=sum; v++) f[v]=-INF;
        f[0]=0;
        for(int i=1; i<all_n; i++)
            for(int v=sum; v>=w[i]; v--)
                f[v]=max(f[v], f[v-w[i]]+w[i]);
        int tmp;
        if(sum%2) tmp=sum+1;
        else tmp=sum;

        int ans=0;
        for(int v=tmp/2; v>=0; v++)
            if(f[v]>0){
                ans=v; break;
            }
        cout<<ans<<" "<<sum-ans<<endl;

    }
    return 0;
}

 

方法2代码:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

const int maxn=2e6+5;
const int INF=0x3f3f3f3f;
int f[maxn], c[maxn], w[maxn];
int main()
{
    //freopen("in.txt", "r", stdin);
    int n;
    while (cin>>n, n>=0)
    {
        int all_n=1, sum=0;
        while(n--)
        {
            int val,num,k; cin>>val>>num;
            sum=sum+val*num;
            for(k=1; k<num; k<<=1){
                w[all_n++]=k*val;
                num=num-k;
            }
            if(num)
                w[all_n++]=num*val;
        }
        memset(f, 0, sizeof(f));
        for(int i=1; i<all_n; i++)
            for(int v=sum/2; v>=w[i]; v--)
                f[v]=max(f[v], f[v-w[i]]+w[i]);
        printf("%d %d\n", sum-f[sum/2], f[sum/2]);
    }
    return 0;
}

 

 

基础背包题集

原文:https://www.cnblogs.com/Yokel062/p/10686493.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!