zoukankan      html  css  js  c++  java
  • hdu-1059(多重背包+二进制优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1059

    题意:输入6个数,每个数ni代表价值为i的物品有ni个。求如果这些物品能均分给两个人,每个人获得的物品的总价值

    相同,就输出“Can be divided.”,否则输出“Can't be divided.”;具体格式见输出格式。

    思路:本来想用dfs做的,后来发现时间超限了,其实可以用多重背包来做,

    每个物品的数量有限,找出是否存在几个物品的价值与物品总价值的一半相同。

    参考文章:https://blog.csdn.net/aaaaacmer/article/details/48543575

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int dp[100100],a[20],sum;
    void f(int cost,int num)
    {
        int i;
        if(cost*num>=sum)
        {
            for(i=cost;i<=sum;i++)
            dp[i]=max(dp[i],dp[i-cost]+cost);
            return ;
        }
        int k=1;
        while(k<num)
        {
            for(i=sum;i>=k*cost;i--)
            dp[i]=max(dp[i],dp[i-cost*k]+cost*k);
            num-=k;
            k*=2;
        }
        for(i=sum;i>=num*cost;i--)
        dp[i]=max(dp[i],dp[i-cost*num]+cost*num);
    }
    int main(void)
    {
        int pt=1,i,j;
        while(cin>>a[1]>>a[2]>>a[3]>>a[4]>>a[5]>>a[6])
        {
            if(!a[1]&&!a[2]&&!a[3]&&!a[4]&&!a[5]&&!a[6]) break;
            sum=0;
            for(i=1;i<=6;i++) sum+=a[i]*i;
            printf("Collection #%d:
    ",pt++);
            if(sum%2)
            {
                printf("Can't be divided.
    
    ");
                continue;
            }
            sum/=2;
            memset(dp,0,sizeof(dp));
            for(i=1;i<=6;i++) f(i,a[i]);
            if(dp[sum]==sum) printf("Can be divided.
    
    ");
            else printf("Can't be divided.
    
    ");
        }
        return 0; 
    }
  • 相关阅读:
    vue项目实践-添加axios封装api请求
    travis-ci 中运行 puppeteer
    ubuntu 16.04 TLS 安装VNC
    duilib bkimage 属性
    Android后台服务拍照
    mongodb 设置用户密码权限
    App爬虫神器mitmproxy和mitmdump的使用
    insserv: Script <name> is broken: incomplete LSB comment.
    ubuntu ssh root登陆
    virtualbox 迁移虚拟机存储位置
  • 原文地址:https://www.cnblogs.com/2018zxy/p/9747969.html
Copyright © 2011-2022 走看看