题目链接:
题意:有价值分别为1,2,3,4,5,6的marbles(大理石)若干,问是否能使这些marbles平分。【marbles总数不超过2e4(很明显这是一个大常数,所以用二进制优化来做)】

My_idea(关于二进制优化)

首先的话我们先看14=1+2+4+7({1,2,4,7}可以组成1到14之间的所有的数,不多也不少,这个很重要必须要不多也不少!如果是{1,2,4,8}那么还会有15,这就不可以!)

所以利用这一点我们可以将num[i]按照二进制划分为1,2,4,……这些数,也就是将num[i]个价值为i的物品划分为了1,2,4,……个价值为i * 1 , i * 2, i * 4……的物品,这样的话我们就可以将后者看成一个数量小的01背包再来处理。(不这样优化的话我们就是一个大常数的多重背包,会T)

其次的话,物品只有价值和数量这两个属性,对于一种物品我们二进制转换之后就只有(新)价值这一个属性,而且我们要的答案是能否将所有的marbles价值平分,所以我们的dp[i]就可以用来看价值为i的状态是不是存在,最后只需要看dp[C]是否存在即可。要注意的就是1、dp[j-val]要存在,dp[j]才能存在;2、dp[0]是背包中无价值的状态,初始化要为1。

My_feeling:

首先就题意来说读了n久没读懂,就是这句话:
The lines consist of six non-negative integers n1, n2, …, n6, where ni is the number of marbles of value i. So, the example from above would be described by the input-line ``1 0 1 2 0 0’’. The maximum total number of marbles will be 20000.
不知道为什么我开始的时候就是觉得是20000是前边说的那个样例的价值,我就说到底是怎么得来的?也太迷了吧??一脸懵……QAQ
后来不行了实在是不懂题意,就看他们的博客,写的题意也就是题目字面意思,输入的六个数是大理石的数量,可是20000到底什么什么鬼???于是又开始一个词一个词读,我的天呐,从前天晚上就读了的题到今天上午终于读懂了,原来是数量和的最大值?!这真的说明了我是个白痴……QAQ

读懂题意之后,开始想题,知道这个该用二进制优化,但是不知道怎么处理,于是就想问问谁,但是又找不到人问(好卑微,没啥熟人),博客吧由于种种原因看不下去,就昨天晚上到现在就一直打开这道题的界面然后心烦、心烦、心烦……就打开QQ音乐听歌……先要positive起来……QAQ

下午要打排位了,不知道吧,因为什么,就强迫自己看博客,完完整整看了一遍代码,然后终于理解了之后就开始自己敲。敲了样例过了,感觉没问题,交!WA!于是发现没有初始化dp[0],理解不够深刻吧,再交还是又WA!然后又看了眼题,发现要每个cases中间有blank line隔开,于是又调整了以下,再交!还是WA!又开始debug,发现num[i]没有判零,改了交,WA!然后又发现后边val没有判零,交了!WA!然后就各种怀疑自己的代码,改了些稀奇古怪的地方还是WA了几次,中间还CE了一次。然后就开始试边界20000,发现直接就运行结束了报错,然后就调试了0 0 0 0 0 2000样例,发现中间 j=num[i]; 这一句敲飘了,写成了num[j]直接就超数组大小了。改完交了终于AC了!QAQ……提起AC又想起跳waacking的AC,interesting!

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <list>
#include <map>
#define P(x) x>0?x:0
#define INF 0x3f3f3f3fusing namespace std;
typedef long long ll;
typedef vector<int>:: iterator VITer;
const int maxN=12e4;int dp[maxN],C;
int num[10];
int val,sum;void init()
{sum=0;memset(dp,0, sizeof(dp));dp[0]=1;//背包内价值为0这个状态是可以存在的
}int main()
{int Case=0;while(true){if(Case)printf("\n");init();for(int i=1;i<=6;i++){scanf("%d",&num[i]);sum+=num[i]*i;}if(!sum)//输入为0 0 0 0 0 0break;if(sum&1)//sum为奇数,一定不能平分{printf("Collection #%d:\nCan't be divided.\n",++Case);continue;}C=sum/2;for(int i=1;i<=6;i++){if(!num[i])//如果是0的话就不能再跑了continue;int j;for(j=1;j<=num[i];j<<=1)//将num[i]个i价值的物品转换为一个01背包,假如说是14=1+2+4+7,{1,2,4,7}可以组成1到14所有的数值,所以将价值重新定义后,就是一个01背包{//(二进制优化->可以将多重背包物品数量的大常数转换为小常数)val=i*j;for(int k=C;k>=val;k--){if(dp[k-val]&&(!dp[k]))//k状态没走过,k-val状态走过,那么此刻加上val就是可走的dp[k]=1;//即dp[(k-val)+val]可以有}num[i]-=j;}j=num[i];//此时的num[j]->2的次幂之外的数val=i*j;if(val)//如果是0就不能跑{for(int k=C;k>=val;k--){if(dp[k-val]&&(!dp[k]))dp[k]=1;//即dp[(k-val)+val]可以有}}}if(dp[C])printf("Collection #%d:\nCan be divided.\n",++Case);elseprintf("Collection #%d:\nCan't be divided.\n",++Case);}return 0;
}

因为一个空格行的输出! PE了5次又!

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <list>
#include <map>
#define INF 0x3f3f3f3f
#define MID l + r >> 1
#define lsn rt << 1
#define rsn rt << 1 | 1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qrusing namespace std;
typedef long long ll;
typedef vector<int>:: iterator VITer;
const int maxN = 12e4 + 5;
const int maxE = 1e4 +5;int a[10];
int dp[maxN];int main()
{int Case = 0;while(~scanf("%d", &a[1])){int sum = a[1];for(int i = 2; i <= 6 ; i ++ ){scanf("%d", &a[i]);sum += a[i] * i;}if(sum == 0)break;if(sum & 1){printf("Collection #%d:\nCan't be divided.\n\n", ++ Case );continue;}int C = sum >> 1;memset(dp, 0, sizeof(dp)); dp[0] = 1;// 目的:找所有apart大理石可的价值for(int val = 1; val <= 6 ; val ++ ) // 价值{for(int num = 1 ; num <= a[val] ; num <<= 1){int new_ = num * val; // 新价值for(int j = C ; j >= new_ ; j --)if(!dp[j] && dp[j - new_])dp[j] = 1;a[val] -= num;}if(a[val]){int new_ = a[val] * val;for(int j = C ; j >= new_ ; j -- )if(!dp[j] && dp[j - new_])dp[j] = 1;}}if(dp[C])printf("Collection #%d:\nCan be divided.\n\n", ++ Case);elseprintf("Collection #%d:\nCan't be divided.\n\n", ++ Case);}return 0;
}

Dividing(HDU 1059)(多重背包_二进制优化)相关推荐

  1. 为了OFFER,菜鸟的我必须搞懂动态规划系列三个背包问题之多重背包(二进制优化方法)

    @Author:Runsen @Date:2020/9/17 多重背包有三层循环,如果数据非常的大,那么程序就会变得非常悲伤.在多重背包的问题,其实更多的是考查多重背包的二进制优化方法.学习二进制优化 ...

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

    问题概述:有一个容量为V的背包和n个物品,第i种物品最多有n[i]件可用,每件体积是w[i],求解将哪些物品装入背 包可使这些物品的价值尽可能接近V但不大于V(POJ1276) 输入样例:       ...

  3. 多重背包的二进制优化(ybtoj-宝物筛选)

    文章目录 题目描述 解析 朴素算法 代码 二进制优化 代码 thanks for reading! 题目描述 解析 朴素算法 首先考虑朴素算法 把数量为num的物体拆成num个子物体 其价值与重量是原 ...

  4. HDU 2844 (多重背包)

    多重背包(二进制优化)模板 题意: 有n个硬币,每一个硬币有自己的数值Vi,其个数为Ci.不同硬币的不同组合能买到不同物品,问在1~V的区间内最多能买到多少不同种类的物品. 思路: 其实题意也就是求硬 ...

  5. 多重背包单调队列优化思路_动态规划入门——多重背包与单调优化

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法与数据结构的第14篇文章,也是动态规划专题的第三篇. 在之前的文章当中,我们介绍了多重背包的二进制拆分的解法.在大多数情况下,这种 ...

  6. 动态规划入门——多重背包与单调优化

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法与数据结构的第14篇文章,也是动态规划专题的第三篇. 在之前的文章当中,我们介绍了多重背包的二进制拆分的解法.在大多数情况下,这种 ...

  7. 多重背包2[二进制位优化]

    数据范围加强一下 0<N≤1000 0<V≤2000 0<vi,wi,si≤2000 这时候O(n3)O(n^3)O(n3)的算法不行,需要优化成O(N∗logs∗V)O(N*log ...

  8. ZCMU 1919: kirito's 星爆气流斩【01背包的二进制优化】

    ZCMU 1919: kirito's 星爆气流斩 Time Limit: 2 Sec  Memory Limit: 128 MB Description 主角kirito是使用世界首款完全潜行游戏& ...

  9. POJ1276 多重背包DP 生命不息优化不止

    POJ1276 多重背包DP题 这道题弄了一个早上-一看题目是多重背包题直接敲了一个三重for循环,无限TLE,下面附上好几种解法. Description A Bank plans to insta ...

最新文章

  1. lvm自动扩容到固定分区脚本
  2. java中gson的简单使用
  3. 容量法和库仑法的异同点_【图文专辑】第十讲:容量法高锰酸盐指数的测定
  4. python list同步删除
  5. Work Measurement - 1
  6. 介绍一下mysql的存储过程和搜索引擎_MySQL基础(四)—存储过程和存储引擎
  7. 新垣结衣AI换脸郭德纲 网友:换脸史上最惨的车祸现场
  8. RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility.
  9. 李宏毅机器学习——结构化支持向量机
  10. 记录一次常见的错误:java.sql.SQLException: Got error 28 from storage engine
  11. MFC 盾webBrowser打开弹出的页面
  12. three.js 学习1
  13. 等价类划分法测试用例设计
  14. php paypal支付接口文档,php 实现PayPal支付
  15. Windows2012R2,2008R2 Internet时间无法同步成功解决方案
  16. SpringBoot(六)打包方式
  17. 从设计的角度看 Redux
  18. 桌面在计算机哪个文件,电脑桌面上的文件在C盘哪个文件里面
  19. virsh 保护命令 virtual protect rebase
  20. JeecgBoot 2.4.6 版本发布,基于代码生成器的企业级低代码平台

热门文章

  1. HR如何招一个靠谱的人
  2. 【String拼接】Go语言字符串如何高效的进行拼接(6种方式进行对比分析)
  3. 什么是功能性材料印刷?
  4. 生活娱乐 杜甫很忙图片全集
  5. 【软件】 UltraCompare(文件比较工具)中文版破解
  6. 一文带你搞懂React路由(详解版)
  7. 网站安全需注意,华为云为企业稳定运营保驾护航
  8. 【图片新闻】具有革命性标志的倾斜旋翼直升机V-22鱼鹰
  9. 3.11 分区存储组织
  10. gt911 1024*600配置表