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("\n");

        cnt = 0;

        for(i = 1; i<=6; i++)  cnt+=i*a[i];

        printf("Collection #%d:\n",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;

}

  

你可能感兴趣的:(div)