D - D 分糖果HDU - 1059(完全背包+二进制优化)
有两个小朋友想要平分一大堆糖果,但他们不知道如何平分需要你的帮助,由于没有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(完全背包+二进制优化)的更多相关文章
- HDU 3591 (完全背包+二进制优化的多重背包)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3591 The trouble of Xiaoqian Time Limit: 2000/1000 M ...
- hdu 2191 (多重背包+二进制优化)
Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品, ...
- hdu 1171 Big Event in HDU(多重背包+二进制优化)
题目链接:hdu1171 思路:将多重背包转为成完全背包和01背包问题,转化为01背包是用二进制思想,即件数amount用分解成若干个件数的集合,这里面数字可以组合成任意小于等于amount的件数 比 ...
- hdu 2191 (多重背包二进制优化)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 实现代码: #include<bits/stdc++.h> using namespac ...
- hdu 2844 多重背包二进制优化
//http://www.cnblogs.com/devil-91/archive/2012/05/16/2502710.html #include<stdio.h> #define N ...
- HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)
HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...
- HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)
HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...
- HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化)
HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化) 题意分析 首先C表示测试数据的组数,然后给出经费的金额和大米的种类.接着是每袋大米的 ...
- hdu1059 多重背包(转换为01背包二进制优化)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1059 之前写过一个多重背包二进制优化的博客,不懂请参考:http://www.cnblog ...
随机推荐
- Spring Cloud Gateway 实现Token校验
在我看来,在某些场景下,网关就像是一个公共方法,把项目中的都要用到的一些功能提出来,抽象成一个服务.比如,我们可以在业务网关上做日志收集.Token校验等等,当然这么理解很狭隘,因为网关的能力远不止如 ...
- 阿里云上docker部署nginx实现反向代理
简介 需要从镜像仓库找到所需要的nginx版本pull下来.(地址:https://hub.docker.com/) 1.docker pull nginx 1.挂载目录 1.1 获取nginx. ...
- java算法--链表
虽然这个文章看着很多,但是大多是对于细节的讲解,如果想要快速了解,可以直接观看末尾代码.上面的代码内容都是来自于文章末尾的代码. 很重要的算法,也是比较简单的算法. 但是在java中,因为不存在c和c ...
- Sequence to Sequence Learning with Neural Networks论文阅读
论文下载 作者(三位Google大佬)一开始提出DNN的缺点,DNN不能用于将序列映射到序列.此论文以机器翻译为例,核心模型是长短期记忆神经网络(LSTM),首先通过一个多层的LSTM将输入的语言序列 ...
- 致远·面向人工智能-逐浪CMS v8.1.2全面发布[全球首个基于dotNET core3.0的中文CMS]
原文:https://www.z01.com/down/3484.shtml 再远, 我都不会停息, 因为技术而生, 因为技术而强, 这是逐浪软件的命与根! 全新打造, 三百多项超级功能, 助你十分钟 ...
- <字符串匹配>KMP算法为何比暴力求解的时间复杂度更低?
str表示文本串,m表示模式串; str[i+j] 和 m[j] 是正在进行匹配的字符; KMP的时间复杂度是O(m+n) , 暴力求解的时间复杂度是O(m*n) KMP利用了B[0:j]和A[i ...
- 今天对C语言不常用的小东西的了解
今天又翻了C语言的书,看到const语句,一时间想不起来到底是干嘛的,看语句const int a=1;明白了这是一个支持常量指定类型的定义常量的关键字,作用几乎与#define一毛一样,但# ...
- 建议8:恰当选用if和switch
相对来说下面几种情况更适合switch结构 枚举表达式的值.这种枚举是可以期望的,平行逻辑关系的 表达式的值具有离散性,不具有线性的非连续的区间值 表达式的值是固定的,不是动态变化的 表达式的值是有限 ...
- 【Weiss】【第03章】练习3.13:桶排序
[练习3.13] 利用社会安全号码对学生记录构成的数组排序.编写一个程序进行这件工作,使用具有1000个桶的基数排序并且分三趟进行. Answer: 首先,对社会安全号码不了解的就把它当成一个不超过9 ...
- defer 链如何被遍历
去年开始写文章的第一篇就是关于 defer,名字比较文艺:<Golang 之轻松化解 defer 的温柔陷阱>,还被吐槽了.因为这篇文章,到<Go 夜读>讲了一期.不过当时纯粹 ...