有两个小朋友想要平分一大堆糖果,但他们不知道如何平分需要你的帮助,由于没有spj我们只需回答能否平分即可。

糖果大小有6种分别是1、2、3、4、5、6,每种若干颗,现在需要知道能不能将这些糖果分成等额的两堆。

一颗大小为6的糖果,可以相当于2颗大小为3的糖果,其他同理,即大小满足加法,但是1颗糖果是不能被拆分的。

Input

多组输入,每行输入6个非负整数,分别表示大小为1、2、3、4、5、6的糖果的数量,若输入6个0代表输入结束。

单种糖果的数量不会超过20000。

Output 每组询问先输出一行 "Collection #k:",k表示第几组询问。

再输出一行表示答案,若能分割,输出 “Can be divided.”,若不能输出 ”Can't be divided.“

每组输出后空一行

Sample Input
1 0 1 2 0 0
1 0 0 0 1 1
0 0 0 0 0 0
Sample Output
Collection #1:
Can't be divided. Collection #2:
Can be divided.

思路

  • 题意: 给我们6种物品,每种物品有各自的数量,第i种物品的价值、与所占的空间均是i,能否将将这个六种物品的价值均分为两份
  • 分析:1.如果6种物品价值之和sum为奇数,显然不可能均分;否则的有可能均分,那么我们把 \(sum/2\)作为的背包的空间,如果我们在dp之后, \(dp[sum/2] == sum/2\), 说明用 sum/2的空间是可以均分的。
  • 代码1:我是把完全背包转01背包了,这样同种物品就转化为了不同的物品,不过显然由于每种的物品数量太多肯定会T
  • 代码2: 则是把完全背包的 每种物品进行 “二进制拆分”这样拆分之后的物品数量就像对于代码1的转化方法大大的减少了

代码一(完全背包转01背包--->T了)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int Len = 200000;
int ar[7], dp[Len]; int main()
{
/* freopen("A.txt","r",stdin); */
int Case = 1;
while(scanf("%d %d %d %d %d %d", &ar[1], &ar[2], &ar[3], &ar[4], &ar[5], &ar[6]) && ar[1] + ar[2] + ar[3] + ar[4] + ar[5] + ar[6])
{
int sum = ar[1]*1 + ar[2]*2 + ar[3]*3 + ar[4]*4 + ar[5]*5 + ar[6]*6;
if(sum % 2)
{
printf("Collection #%d:\nCan't be divided.\n\n", Case ++);
continue;
} sum /= 2;
for(int i = 0; i <= sum; i ++)
dp[i] = 0; for(int i = 1; i <= 6; i ++) //把多重背包拆分成一个一个的01背包
for(int j = 1; j <= ar[i]; j ++)
for(int k = sum; k >= ar[i]; k --)
dp[k] = max(dp[k], dp[k - i] + i);
if(dp[sum] == sum)
printf("Collection #%d:\nCan be divided.\n\n", Case ++);
else
printf("Collection #%d:\nCan't be divided.\n\n", Case ++);
} return 0;
}

代码二(完全背包--->二进制优化)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int Len = 200000;
int ar[7], dp[Len], w[Len]; int main()
{
/* freopen("A.txt","r",stdin); */
int Case = 1;
while(scanf("%d %d %d %d %d %d", &ar[1], &ar[2], &ar[3], &ar[4], &ar[5], &ar[6]) && ar[1] + ar[2] + ar[3] + ar[4] + ar[5] + ar[6])
{
int sum = ar[1]*1 + ar[2]*2 + ar[3]*3 + ar[4]*4 + ar[5]*5 + ar[6]*6;
if(sum % 2)
{
printf("Collection #%d:\nCan't be divided.\n\n", Case ++);
continue;
} //把某个物品有多个的进行二进制拆分
int cnt = 1;
for(int i = 1; i <= 6; i ++)
{
for(int j = 1; j <= ar[i]; j <<= 1)
w[cnt ++] = j * i, ar[i] -= j;
if(ar[i]) //注意:这个地方剩余的数,不要忘了添加上去!
w[cnt ++] = ar[i] * i;
} sum /= 2;
for(int i = 0; i <= sum; i ++)
dp[i] = 0; for(int i = 1; i < cnt; i ++) //把通过二进制优化以后,就变成了一个简单的背包问题了
for(int k = sum; k >= w[i]; k --)
dp[k] = max(dp[k], dp[k - w[i]] + w[i]);
if(dp[sum] == sum)
printf("Collection #%d:\nCan be divided.\n\n", Case ++);
else
printf("Collection #%d:\nCan't be divided.\n\n", Case ++);
} return 0;
}

D - D 分糖果HDU - 1059(完全背包+二进制优化)的更多相关文章

  1. HDU 3591 (完全背包+二进制优化的多重背包)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3591 The trouble of Xiaoqian Time Limit: 2000/1000 M ...

  2. hdu 2191 (多重背包+二进制优化)

    Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品, ...

  3. hdu 1171 Big Event in HDU(多重背包+二进制优化)

    题目链接:hdu1171 思路:将多重背包转为成完全背包和01背包问题,转化为01背包是用二进制思想,即件数amount用分解成若干个件数的集合,这里面数字可以组合成任意小于等于amount的件数 比 ...

  4. hdu 2191 (多重背包二进制优化)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 实现代码: #include<bits/stdc++.h> using namespac ...

  5. hdu 2844 多重背包二进制优化

    //http://www.cnblogs.com/devil-91/archive/2012/05/16/2502710.html #include<stdio.h> #define N ...

  6. HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)

    HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...

  7. HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)

    HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...

  8. HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化)

    HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化) 题意分析 首先C表示测试数据的组数,然后给出经费的金额和大米的种类.接着是每袋大米的 ...

  9. hdu1059 多重背包(转换为01背包二进制优化)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1059 之前写过一个多重背包二进制优化的博客,不懂请参考:http://www.cnblog ...

随机推荐

  1. js 面向对象中,定义一个函数的过程

    定义一个函数做的两件事:1: 实例化一个Function对象:2: 实例化一个Object对象,并给该函数扩展prototype属性指向这个构造函数 大致过程如图所示: 每一种引用类型(函数,对象,数 ...

  2. python-面向对象小结

    面向对象 小结 1:面向对象:就是一种编程思想 简称oop,指挥某某完成能完成的功能 2:面向对象与面向过程的优缺点 : 面向过程: 优点: 复杂问题简答化(一步一步解决), 流程化, 缺点:机械化 ...

  3. vue的子组件不能进行router的切换

    在用vue开发过程中,偶然一次使用在子组件中进行router的切换,发现不起作用,后来才反应过来,子组件只是一个组件,vue的路由的切换只能是在父组件(也就是真正的页面)里面进行跳转!

  4. 逐浪web无障碍与国际化以及全民族语言支持白皮书

    北京时间2019年5月10日,领先的门户网站与WEB内核服务厂商--上海Zoomla!逐浪CMS团队发布其年度重榜产品:逐浪CMS全民族语言与国际版,体验站点:http://demo2.z01.com ...

  5. flask 设置https请求 访问flask服务器

    学习过程中想要学教程中一样,做个假的微信公众号推送,不过去了微信开发文档怎么一直说需要https的请求(教学中没有说需要https,一直是http) 但是我的服务器只能使用http请求访问,如果硬是要 ...

  6. GitHub 热点速览 Vol.11:回暖的 GitHub 迎来上千星的图片流项目

    作者:HelloGitHub-小鱼干 摘要:连着两周成绩平平的 GitHub Trending 榜,终于和三月的天气一样进入全面变暖的模式,无论是本周刚开源搭乘 ocr 热点并获得 1,500+ st ...

  7. vscode 新版设置备份20200221 settings.json

    vscode 新版设置备份20200221 { "sync.gist": "9e6a5f7e8c52047b03c8732ff88aab0e", "s ...

  8. 五分钟了解Semaphore

    一.前言 多个线程之间的同步,我们会用到Semaphore,翻译成中文就是信号量.使用Semaphore可以限制多个线程对同一资源的访问.我们先看下C#中对Semaphore的定义,如下图: 翻译成中 ...

  9. No compiler is provided in this environment报错解决方案

  10. DVWA Command Injection 解析

    命令注入,即 Command Injection.是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的. 在Web应用中,有时候会用到一些命令执行的函数,如php中system.ex ...