HDU 1059 母函数

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1059
题意:1-6价值的硬币若干,问能不能平分。这道题一开始是思考的背包问题。因为这涉及到能不能刚好一半的容量。同理,既然是这样的,也可以用母函数。母函数就明显比背包会更简单。只要最后判断有没有系数就行了。
然后我有一句MMP一定要讲。我PE了1个小时。透李奶奶。因为我判断sum&1直接输出不行的时候少了个回车。我一直在后面的输出找格式错误。尴尬了。以后牢记教训。然后这个题的背包等我刷46DP的时候肯定会碰到再用DP做一遍。

#include<bits/stdc++.h>
#define INF 1e18
#define inf 1e9
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define IOS ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std ;
typedef long long ll;
typedef unsigned long long ull;
const int _max = 20000*6+5;   
// c1是保存各项质量砝码可以组合的数目  
// c2是中间量,保存每一次的情况  
int c1[_max], c2[_max];     
int main(){
    IOS;
    int num[7],Cas = 0;
    while(++Cas){
        int maxn = 0;
        for(int i = 1 ; i <= 6 ; i++) cin>>num[i];
        if(!num[1]&&!num[2]&&!num[3]&&!num[4]&&!num[5]&&!num[6]) break;
        for(int i = 1 ; i <= 6 ; i++) num[i] %= 60;
        for(int i = 1 ; i <= 6 ; i++)
            maxn += num[i]*i;
        if(maxn&1){
            cout<<"Collection #"<<Cas<<":"<<endl<<"Can't be divided."<<endl<<endl;
            continue;
        }
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));
        for(int i = 0 ; i <= num[1]*1 ; i++) c1[i] = 1;
        int sum = num[1]*1;
        for(int k = 2 ; k <= 6 ; k++){
            for(int i = 0 ; i <= sum ; i++)
                for(int j = 0 ; j <= num[k]*k ;j+=k){
                    c2[i+j] += c1[i];
                }
            sum += num[k]*k;
            for(int i = 0 ; i <= sum ; i++){
                c1[i] = c2[i];
                c2[i] = 0;
            }
        }
    /*  for(int i = 1 ; i <= maxn ; i++)
            cout<<c1[i]<<' ';
        cout<<endl;*/
        bool flag = true;
        if(c1[(maxn>>1)] == 0) flag = false;
        if(!flag) cout<<"Collection #"<<Cas<<":"<<endl<<"Can't be divided."<<endl;
        else cout<<"Collection #"<<Cas<<":"<<endl<<"Can be divided."<<endl;
        cout<<endl;
    }
    return 0;  
}  

猜你喜欢

转载自blog.csdn.net/qq_38987374/article/details/79604354