【bzoj2064】【分裂】状态压缩表示合并子集
来源:互联网 发布:宝信软件同花顺 编辑:程序博客网 时间:2024/05/15 23:52
(上不了p站我要死了,画师当然是wlop大大啦)
感觉这个做法还是挺难想的。
但还是总结一下思路吧。。
“只可意会不可言传的状压dp”(乱说)
Description
背景: 和久必分,分久必和。。。 题目描述: 中国历史上上分分和和次数非常多。。通读中国历史的WJMZBMR表示毫无压力。 同时经常搞OI的他把这个变成了一个数学模型。 假设中国的国土总和是不变的。 每个国家都可以用他的国土面积代替, 又两种可能,一种是两个国家合并为1个,那么新国家的面积为两者之和。 一种是一个国家分裂为2个,那么2个新国家的面积之和为原国家的面积。 WJMZBMR现在知道了很遥远的过去中国的状态,又知道了中国现在的状态,想知道至少要几次操作(分裂和合并各算一次操作),能让中国从当时状态到达现在的状态。
Input
第一行一个数n1,表示当时的块数,接下来n1个数分别表示各块的面积。 第二行一个数n2,表示现在的块,接下来n2个数分别表示各块的面积。
Output
一行一个数表示最小次数。
Sample Input
1 6
3 1 2 3
Sample Output
2
数据范围:
对于100%的数据,n1,n2<=10,每个数<=50
对于30%的数据,n1,n2<=6,
当然,我们很自然的想到一种方法,就是先把所有的国家合并起来,再挨个拆开,这样的次数是n+m-2,也就是上限。
那么什么时候可以使操作次数减少呢?我们发现,当有一些子集的和相等时,直接将这些合并再拆开,就可以免去多余的合并操作。(然而我这一步愣是没想出来)
从反方面想,每当找到这样的子集,就相当于找到了一次没用的操作,就可以拿上限去减。但是,如果合并方式不同,可能会产生不同的“没用操作”,而我们希望找到一种“没用操作”最多的操作方案,此时就是dp了。
而每一个国家可以被选或不被选,在有两种状态的情况下,我们很容易想到状压,而数据范围也是可以的。
那么对于一个子集状态的01串f[s](这里我将原来以及现在的国家状态合并到了一个二进制数中),这样的集合一定是由其一个子集和一个元素(国家)合并过来,不同的合并方式会造成不同的“没用操作”。所以对于每个集合,枚举集合中的每个元素,就相当于枚举不同的合并操作,取max即可。
如果该状态s中原来国家和现在国家的面积之和相等,则该状态也是一个“没用操作”,答案要++
完整代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int f[1<<20],sum1[1<<10],sum2[1<<10];int n,m,w[15],v[15];int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&w[i]); scanf("%d",&m); for(int i=1;i<=m;i++) scanf("%d",&v[i]); for(int i=1;i<(1<<n);i++){ for(int j=i,k=1;j;j>>=1,k++) if(j&1) sum1[i]+=w[k]; } for(int i=1;i<(1<<m);i++){ for(int j=i,k=1;j;j>>=1,k++) if(j&1) sum2[i]-=v[k]; } for(int i=1;i<(1<<(n+m));i++){ for(int j=i,k=0;j;j>>=1,k++) if(j&1) f[i]=max(f[i],f[i^(1<<k)]); if(sum1[i&((1<<n)-1)]+sum2[i>>n]==0) f[i]++; } printf("%d\n",n+m-2*f[(1<<(n+m))-1]); return 0;}
- 【bzoj2064】【分裂】状态压缩表示合并子集
- 【BZOJ2064】分裂
- bzoj2064: 分裂
- bzoj2064 分裂
- BZOJ2064 分裂
- bzoj2064分裂
- BZOJ2064 分裂
- 【bzoj2064】分裂
- BZOJ2064状态压缩动态规划
- [bzoj2064] 分裂 状压dp
- bzoj 2064: 分裂【状态压缩】
- [BZOJ2064]分裂(状压dp)
- [BZOJ2064]分裂(状压dp)
- bzoj2064 分裂(状压DP)
- BZOJ2064:分裂(状压DP)
- 【BZOJ2064】分裂(状压dp+奇技淫巧)
- bzoj2064 分裂 状压dp(神题)
- [BZOJ2064]-分裂-状压dp思路好题
- Hive自定义UDF函数
- BZOJ 2150 浅谈二分图Bipartite Graph及DAG最小路径覆盖
- 非阻塞模式(ioctlsocket)
- PhantomJS快速入门
- IOCP模型与网络编
- 【bzoj2064】【分裂】状态压缩表示合并子集
- Windows Socket 编程_单个服务器对多个客户端简单通讯
- LeetCode[567]Permutation in String(Java)
- I2S音频总线学习(一)数字音频技术
- bzoj 2748 音量调节 DP 解题报告
- 数据降维---LLE(Locally Linear Embedding)---局部线性嵌入(1)
- javascript实现垂直导航在可视区范围显示
- 完成1500万元Pre-A轮融资 火绒为何牵手天融信?
- Excel2013打印时怎么固定表头及表尾让打印后的每页都可以看得到