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 ...
随机推荐
- Flask css 无法实时更新
css代码改完了,但是查看网页源代码css的内容还是很久之前的,根本没有更新 解决方法: 1.浏览器缓存.使用ctrl+F5刷新一下页面 2. 3. from datetime import time ...
- 19 JPQL
使用Spring Data JPA提供的查询方法已经可以解决大部分的应用场景,但是对于某些业务来说,我们还需要灵活的构造查询条件,这时就可以使用@Query注解,结合JPQL的语句方式完成查询 @Qu ...
- php判断二个数最大公约数
$m = isset($_GET['m']) ? $_GET['m'] : 12; $n = isset($_GET['n']) ? $_GET['n'] : 8; //判断mn的大小 if($m&g ...
- 如何从普通程序员晋升为架构师 面向过程编程OP和面向编程OO
引言 计算机科学是一门应用科学,它的知识体系是典型的倒三角结构,所用的基础知识并不多,只是随着应用领域和方向的不同,产生了很多的分支,所以说编程并不是一件很困难的事情,一个高中生经过特定的训练就可以做 ...
- qtp10安装步骤(比较完整)
在安装qtp之前,要提前安装软件(不知道是干嘛的,反正安装就完了),右键--管理员运行完成安装,如下图: 解压qtp镜像: 双击setup: 第一步,点击第一排 第二步, 注:安装QTP系统提示“ 计 ...
- 前端BOM和DOM
前端基础之BOM和DOM 前戏 到目前为止,我们已经学过了JavaScript的一些简单的语法.但是这些简单的语法,并没有和浏览器有任何交互. 也就是我们还不能制作一些我们经常看到的网页的一些 ...
- vue — 创建vue项目
创建vue项目 在程序开发中,有三种方式创建vue项目,本地引入vuejs.使用cdn引入vuejs.使用vue-cli创建vue项目.其中vue-cli可以结合webpack打包工具使用,大大方便了 ...
- jmeter 性能测试基本过程及示例
jmeter 为性能测试提供了一下特色: jmeter 可以对测试静态资源(例如 js.html 等)以及动态资源(例如 php.jsp.ajax 等等)进行性能测试jmeter 可以挖掘出系统最大能 ...
- spring Boot登录验证之验证码 邮箱
一 验证码 登录login.jsp <%@ page contentType="text/html;charset=UTF-8" language="java&qu ...
- Socket编程简介
目录 背景 基础 流程 参考 本文系读书笔记,非深入研究,也无代码,如非所需,请见谅. 哦,这里有份不错的:Linux的SOCKET编程详解 背景 花了好久的时间(大约一周,我太垃圾)看完了一篇英文文 ...