bzoj2064分裂(dp)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>

using namespace std;

inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}

const int maxn = 11;

int n,m;
int sa[1 << maxn],sb[1 << maxn];
int f[1 << maxn][1 << maxn];
int a[maxn],b[maxn];

int counta(int x)
{
int cnt=0;
for (int i=1;i<=n;i++)
if (x & (1 << (i-1))) cnt+=a[i];
return cnt;
}

int countb(int x)
{
int cnt=0;
for (int i=1;i<=m;i++)
if (x & (1 << (i-1))) cnt+=b[i];
return cnt;
}

int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
m=read();
for (int i=1;i<=m;i++) b[i]=read();
for (int i=1;i<(1 << n);i++) sa[i]=counta(i);
for (int i=1;i<(1 << m);i++) sb[i]=countb(i);
for (int i=1;i<(1 << n);i++)
for (int j=1;j<(1 << m);j++)
{
for (int k =1;k<=n;k++)
{
int p = 1 << (k-1);
if (p&i) f[i][j]=max(f[i][j],f[i-p][j]);
}
for (int k=1;k<=m;k++)
{
int p = 1 << (k-1);
if (p&j) f[i][j]=max(f[i][j],f[i][j-p]);
}
if (sa[i]==sb[j]) f[i][j]++;
}
printf("%d",n+m-2*f[(1<<n)-1][(1<<m)-1]);
return 0;
}


posted @ 2018-12-22 13:42  y_immortal  阅读(80)  评论(0编辑  收藏  举报