分裂 状压DP
分裂 状压DP
题目描述:
和久必分,分久必和。。。
中国历史上上分分和和次数非常多。。通读中国历史的\(WJMZBMR\)表示毫无压力。同时经常搞OI的他把这个变成了一个数学模型。
假设中国的国土总和是不变的。 每个国家都可以用他的国土面积代替, 又两种可能,一种是两个国家合并为\(1\)个,那么新国家的面积为两者之和。 一种是一个国家分裂为\(2\)个,那么\(2\)个新国家的面积之和为原国家的面积。
\(WJMZBMR\)现在知道了很遥远的过去中国的状态,又知道了中国现在的状态,想知道至少要几次操作(分裂和合并各算一次操作),能让中国从当时状态到达现在的状态。
code:
//
#include<bits/stdc++.h>
using namespace std;
#define maxnn 6666
int n,m;
int sum1[maxnn];
#define lowbit(i) i&(-i)
int sum2[maxnn];
int dp[maxnn][maxnn];
int all1,all2;
int main()
{
cin>>n;
all1=(1<<n)-1;
for(int i=1;i<=n;i++) scanf("%d",&sum1[1<<i-1]);
cin>>m;
all2=(1<<m)-1;
for(int i=1;i<=m;i++) scanf("%d",&sum2[1<<i-1]);
for(int i=0;i<=all1;i++) sum1[i]=sum1[i^lowbit(i)]+sum1[lowbit(i)];
for(int i=0;i<=all2;i++) sum2[i]=sum2[i^lowbit(i)]+sum2[lowbit(i)];
for(int i=0;i<=all1;i++)
{
for(int j=0;j<=all2;j++)
{
for(int p=1;p<=n;p++)
if(i&(1<<p-1))
dp[i][j]=max(dp[i][j],dp[i^(1<<p-1)][j]);
for(int p=1;p<=m;p++)
if(j&(1<<p-1))
dp[i][j]=max(dp[i][j],dp[i][j^(1<<p-1)]);
if(sum1[i]==sum2[j]&&(i!=0&&j!=0)) dp[i][j]++;
}
}
cout<<n+m-2*dp[all1][all2];
}
刀剑映出了战士的心。而我的心,漆黑且残破