BZOJ2064 分裂

来源:互联网 发布:雪梨网红淘宝店链接 编辑:程序博客网 时间:2024/04/29 10:53

都是这句话什么玩意……

我们发现我们可以把分裂过程分成几组,每一组都是初始那一堆合成一堆再分裂成结果那一堆

这样的话每一组只要满足初始的和与结束的和相等即可

所以答案就是n1+n2-2*最多组数

f[i]表示集合为i,最多组数是多少

然后转移转移……

如果这个整个集合都是和为0那么一定存在一个在一个和为0的组里

如果整个集合不为0那么一定存在一个不在组里

所以把每个都单拎出来然后转移就好了……

D

P

#include<iostream>#include<cstring>#include<cstdio>#include<cstdlib>#include<cmath>#include<ctime>#include<algorithm>#include<iomanip>#include<map>#include<set>#include<bitset>#include<queue>#include<stack>#include<vector>using namespace std;#define MAXN 510#define MAXM 2000010#define INF 1000000000#define eps 1e-8#define MOD 1000000007#define ll long longint n,m;int v[MAXN];int s[MAXM],f[MAXM];int main(){int i,j;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&v[i]);}scanf("%d",&m);n+=m;for(;i<=n;i++){scanf("%d",&v[i]);v[i]*=-1;}int N=(1<<n);for(i=1;i<N;i++){for(j=1;j<=n;j++){if(i&(1<<(j-1))){break;}}s[i]=s[i^(1<<(j-1))]+v[j];for(j=1;j<=n;j++){if(i&(1<<(j-1))){f[i]=max(f[i],f[i^(1<<(j-1))]+(!s[i]));}}}printf("%d\n",n-f[N-1]*2);return 0;}/**/


0 0
原创粉丝点击