BZOJ 2064: 分裂 状压dp
2064: 分裂
题目连接:
http://www.lydsy.com/JudgeOnline/problem.php?id=2064
Description
背景: 和久必分,分久必和。。。 题目描述: 中国历史上上分分和和次数非常多。。通读中国历史的WJMZBMR表示毫无压力。 同时经常搞OI的他把这个变成了一个数学模型。 假设中国的国土总和是不变的。 每个国家都可以用他的国土面积代替, 又两种可能,一种是两个国家合并为1个,那么新国家的面积为两者之和。 一种是一个国家分裂为2个,那么2个新国家的面积之和为原国家的面积。 WJMZBMR现在知道了很遥远的过去中国的状态,又知道了中国现在的状态,想知道至少要几次操作(分裂和合并各算一次操作),能让中国从当时状态到达现在的状态。
Input
第一行包含一个整数N。
接下来N行,每行描述一个怪兽的信息;
其中第i行包含若干个整数,前三个整数为Si,Ki和Ri,表示对于i号怪兽,
普通攻击需要消耗Si的体力,法术攻击需要消耗Ki的体力,同时i号怪兽死亡后会产生Ri个新的怪兽。表示一个新出现的怪兽编号。同一编号的怪兽可以出现多个。
Output
一行一个数表示最小次数。
Sample Input
1 6
3 1 2 3
Sample Output
2
数据范围:
对于100%的数据,n1,n2<=10,每个数<=50
对于30%的数据,n1,n2<=6,
Hint
题意
题解:
我不会,智商太低了,代码是别人给的。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 20;
int f[1<<maxn],sum[1<<maxn],n,m,x;
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&sum[1<<i]);
}
scanf("%d",&m);
for(int i=n;i<n+m;i++){
scanf("%d",&x);
sum[1<<i]=-x;
}
int End = 1<<(n+m);
for(int i=1;i<End;i++){
int t=i&(-i);
sum[i]=sum[t]+sum[i-t];
for(int j=0;j<n+m;j++){
if(i&(1<<j))
f[i]=max(f[i],f[i^(1<<j)]);
}
if(!sum[i])f[i]++;
}
cout<<n+m-2*f[End-1]<<endl;
}