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

    http://acm.hdu.edu.cn/showproblem.php?pid=1059

    题意: 有两个人一起收集石头 石头的重量有六种 每种都有一定的数量 

              现在两人想要将所有石头按重量来平分 问 可不可以做到

    思路:

    这题可以用多重背包解决 

    把多重背包转化为01背包 如果dp[tot/2]==1 则可以平分

    否则不能

    因为数量较多 还要加个二进制优化 

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <iostream>
    #include <queue>
    #include <algorithm>
    typedef long long LL;
    using namespace std;
    int dp[121000];
    int main()
    {
        int a[10],ca = 1,e = 0;
        while (scanf("%d",&a[1]))
        {
            int i,j;
            for(i = 2; i<=6; i++)
                scanf("%d",&a[i]);
            int cnt = 0;
            for(i = 1; i<7;i++)
            {
                if(a[i] == 0)
                    cnt++;
            }
            if(cnt == 6)
                break;
            if(e++)
                printf("
    ");
            cnt = 0;
            for(i = 1; i<=6; i++)  cnt+=i*a[i];
            printf("Collection #%d:
    ",ca++);
            if(cnt%2 ==1 )
            {
                cout<<"Can't be divided."<<endl;
                continue;
            }
            int ans = cnt/2;
    
    
    
            memset(dp,-1,sizeof(dp));
            dp[0] = 1;
            int k;
    
    
            for(i = 1; i<7; i++) //石头重量为 i
            {
                int tot = a[i];// 重量为 i 的石头 有 tot个
                for(j = 1; j <= tot;j*=2)//  j 个石头
                {
                    tot -= j;
                    for(k = ans;k>=i*j;k--)//  当前状态
                    {
                        int w = i*j;
                        if(dp[k - w] !=-1) dp[k] = 1;
                    }
                }
                if(tot!=0)
                {
                    for(k = ans;k>=i*tot;k--)
                    {
                        int w = i*tot;
                        if(dp[k - w] !=-1) dp[k] = 1;
                    }
                }
            }
            if(dp[ans] == 1)
                cout<<"Can be divided."<<endl;
            else
                cout<<"Can't be divided."<<endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    操作系统原理
    Linux三剑客正则表达式
    Linux通配符知识深度实践详解
    Linux文件属性之时间戳及文件名知识详解
    Linux系统文件权限
    date:显示与设置系统时间
    正则表达式--三剑客简单应用
    Linux习题小结
    Linux系统文件属性知识
    Linux系统目录结构知识
  • 原文地址:https://www.cnblogs.com/sola1994/p/3926733.html
Copyright © 2011-2022 走看看