【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;

}

时间: 2024-08-26 15:39:38

【bzoj2064】分裂【压状dp】的相关文章

bzoj2064: 分裂(状压dp)

Description 背景: 和久必分,分久必和... 题目描述: 中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力. 同时经常搞OI的他把这个变成了一个数学模型. 假设中国的国土总和是不变的. 每个国家都可以用他的国土面积代替, 又两种可能,一种是两个国家合并为1个,那么新国家的面积为两者之和. 一种是一个国家分裂为2个,那么2个新国家的面积之和为原国家的面积. WJMZBMR现在知道了很遥远的过去中国的状态,又知道了中国现在的状态,想知道至少要几次操作(分裂和合并

SPOJ BALNUM Balanced Numbers 状压+数位DP

一开始想了一个用二进制状压的方法,发现空间需要的太大,光光memset都要超时 = = 其实不用每次都memset 也可以用三进制,一开始直接打表出所有的状态转移就好 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream&g

POJ 1155 树状dp

TELE Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3856   Accepted: 2054 Description A TV-network plans to broadcast an important football match. Their network of transmitters and users can be represented as a tree. The root of the tre

洛谷P1122 最大子树和 (树状dp)

题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明就向老师提出了这个问题: 一株奇怪的花卉,上面共连有N 朵花,共有N-1条枝干将花儿连在一起,并且未修剪时每朵花都不是孤立的.每朵花都有一个“美丽指数”,该数越大说明这朵花越漂亮,也有“美丽指数”为负 数的,说明这朵花看着都让人恶心.所谓“修剪”,意为:去掉其中的一条枝条,这样一株花就成了两株,扔掉

POJ 1463 树状dp

Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 6629   Accepted: 3058 Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad

POJ 2342 树状dp

Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4606   Accepted: 2615 Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure

poj1947--Rebuilding Roads(树状dp)

Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9496   Accepted: 4316 Description The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, number 1..N) after the terrible earthquake last May. The

POJ_2342_树状dp

http://poj.org/problem?id=2342 第一道树状dp,入门题,用vector构建有向图. #include<iostream> #include<cstring> #include<cstdio> #include<vector> using namespace std; int happy[6050],last[6050],dp[6050][2]; vector<int> v[6050]; vector<int&g

洛谷P2015 二叉苹果树(树状dp)

题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树 2 5 \ / 3 4 \ / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=100). N表示树