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;
}
posted @ 2016-07-10 17:27  qscqesze  阅读(367)  评论(0编辑  收藏  举报