【bzoj2064】分裂【压状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,
思路:想了很久还是找了解题报告,然后就醉了,齐刷刷一片只可意会不可言传,那就意会吧。。。。。又醉了 每份代码都差不多连pascal都是类似1<<i>>1这种神奇的写法
YY了很久,最优方案中出现的所有数一定是一开始两个数列中出现过的数,首先找一个操作数的上界,那一定是n+m,显然只要把第一个数列n次加起来加成一个数,然后再m次分割分成数列2即可
如果已经有a数列里的一坨数的和等于b数列里一坨数的和的话,那先把这两坨数搞成相同的,就可以在上界的基础上减少两次操作,也就是将这两坨数的和合到总和里去,和从总和里分出来的那两次操作省去了,然后再看这两坨数里面最大的和相等的部分,这就是最优子结构了,就可以用DP愉快地搞定了
DP[S][T]表示a数列选中的方案为S,b数列中选中方案为T,两坨数相同的最大值,由上所述,每个相同能减少两次操作,因此答案就是n+m-dp[(1<<(n))-1][(1<<(m))-1]
#include<iostream>
#include<cstdio>
#define maxn 100009
using namespace std;
int a[maxn],b[maxn],suma[maxn],sumb[maxn];
int dp[2000][2000];
void dfs(int k,int state,int *a,int s,int *ans)
{
if(k==a[0]+1)return ;
ans[state<<(a[0]-k)]=s;
dfs(k+1,state*2+1,a,s+a[k+1],ans);
dfs(k+1,state*2,a,s,ans);
}
int main()
{
scanf("%d",&a[0]);
for(int i=1;i<=a[0];i++)scanf("%d",&a[i]);
scanf("%d",&b[0]);
for(int i=1;i<=b[0];i++)scanf("%d",&b[i]);
dfs(0,0,a,0,suma);
dfs(0,0,b,0,sumb);
for(int i=1;i<=(1<<a[0])-1;i++)
for(int j=1;j<=(1<<b[0])-1;j++)
{
for(int k=1;k<=a[0];k++)
{
int u=1<<(k-1);
if((i&u)>0)dp[i][j]=max(dp[i][j],dp[i-u][j]);
}
for(int k=1;k<=b[0];k++)
{
int u=1<<(k-1);
if((j&u)>0)dp[i][j]=max(dp[i][j],dp[i][j-u]);
}
if(suma[i]==sumb[j])dp[i][j]++;
}
printf("%d\n",a[0]+b[0]-2*dp[(1<<(a[0]))-1][(1<<(b[0]))-1]);
return 0;
}
【bzoj2064】分裂【压状dp】的更多相关文章
- FZU 2186 小明的迷宫 【压状dp】
Problem Description 小明误入迷宫,塞翁失马焉知非福,原来在迷宫中还藏着一些财宝,小明想获得所有的财宝并离开迷宫.因为小明还是学生,还有家庭作业要做,所以他想尽快获得所有财宝并离开迷 ...
- bzoj2064: 分裂(状压dp)
Description 背景: 和久必分,分久必和... 题目描述: 中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力. 同时经常搞OI的他把这个变成了一个数学模型. 假设中 ...
- 2018.10.24 bzoj2064: 分裂(状压dp)
传送门 状压dp好题. 考虑对于两个给出的集合. 如果没有两个元素和相等的子集,那么只能全部拼起来之后再拆开,一共需要n1+n2−2n1+n2-2n1+n2−2. 如果有呢? 那么对于没有的就是子问题 ...
- BZOJ_2064_分裂_状压DP
BZOJ_2064_分裂_状压DP Description 背景: 和久必分,分久必和... 题目描述: 中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力. 同时经常搞OI的 ...
- 树状DP (poj 2342)
题目:Anniversary party 题意:给出N各节点的快乐指数,以及父子关系,求最大快乐指数和(没人职员愿意跟直接上司一起玩): 思路:从底向上的树状DP: 第一种情况:第i个员工不参与,F[ ...
- poj3659树状DP
Cell Phone Network Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6273 Accepted: 225 ...
- hdu 1561 The more, The Better_树状dp
题目链接 题意:给你一棵树,各个节点都有价值(除根节点),从根节点出发,选择m个节点,问最多的价值是多小. 思路:很明显是树状dp,遍历树时背包最优价值,dp[i][k]=max{dp[i][r]+d ...
- poj 2342 Anniversary party_经典树状dp
题意:Ural大学有n个职员,1~N编号,他们有从属关系,就是说他们关系就像一棵树,父节点就是子节点的直接上司,每个职员有一个快乐指数,现在要开会,职员和职员的直接上司不能同时开会,问怎才能使开会的快 ...
- 树状DP HDU1520 Anniversary party
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题意:职员之间有上下级关系,每个职员有自己的happy值,越高在派对上就越能炒热气氛.但是必须是 ...
随机推荐
- jQuery 使用问题
attr('checked', 'checked')调用多次仅第一次生效 使用attr()获取这些属性的返回值为String类型,如果被选中(或禁用)就返回checked.selected或disab ...
- React学习(2)—— 组件的运用和数据传递
React官方中文文档地址: https://doc.react-china.org/ 了解了组件之后,就需要理解“Props”和“State”的用法.首先来介绍State,State按照字面意 ...
- 类的特殊方法"__new__"详解
上代码! class A: def __new__(cls, *args, **kwargs): obj = super().__new__(cls) print("__new__ &quo ...
- QQ运动,新楛的马桶还在香,营销人不应摒弃。
QQ运动,都说新楛的马桶还香三天,为毛你这般明日黄花,为营销人所弃. QQ运动,一个差不多被遗忘的冷却地带,却圈粉无数,以性感.狂野.妖艳.线条.汗水等秀元素贯穿始终,狼友显露于此,爱美的女性也未曾缺 ...
- ECSHOP和SHOPEX快递单号查询顺丰插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- Logistic Regression学习笔记
1.李航<统计学习方法>: 2.https://blog.csdn.net/laobai1015/article/details/78113214 3.http://www.cnblogs ...
- POJ3687 反向拓扑排序
Labeling Balls Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16032 Accepted: 4713 D ...
- 002---time & datetime
time & datetime 时间模块 分类 时间戳 时间字符串 时间元祖 定义 UTC:格林威治时间,世界标准时间,中国(UTC + 8) 时间戳:1970-01-01 0:0:0 开始按 ...
- 002---Python基本数据类型--字符串
字符串 .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1p ...
- Python3乘法口诀表(由上至下+由下至上)
一.所用知识点: 1.变量的使用. 2.循环语句的使用,这里用到的是双while循环.当然,使用其他的循环去做也是可以的.我认为,对于刚刚接触编程的人来说,使用双while循环比较容易理解. 3.使用 ...