Sharing Chocolate UVA - 1099

问题

https://vjudge.net/problem/UVA-1099

分析

时间是 O ( x 3 n ) O(x3^n) ,状态 O ( x 2 n ) O(x2^n) .

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long LL;
const int maxn=15;
int n,x,y,a[maxn],kase=1,vis[(1<<maxn)+5][105],dp[(1<<maxn)+5][105],s[(1<<maxn)+5];

int DP(int cur,int row){
    int &temp=dp[cur][row];
    if(vis[cur][row]==kase) return temp;
    vis[cur][row]=kase;
    int cnt=0;
    for(int i=0;i<n;++i) if(cur&(1<<i)) ++cnt;
    if(cnt==1) return temp=1;
    temp=0;
    int col=s[cur]/row;
    for(int s0=(cur-1)&cur;s0;s0=(s0-1)&cur){
        if(s[s0]%row==0){
            temp = DP(s0,min(row,s[s0]/row)) && DP(cur-s0,min(row,(s[cur]-s[s0])/row));
            if(temp) return 1;
        }
        if(s[s0]%col==0){
            temp= DP(s0,min(col,s[s0]/col)) && DP(cur-s0,min(col,(s[cur]-s[s0])/col));
            if(temp) return 1;
        }
    }
    return temp=0;
}

int main(void){
    while(scanf("%d",&n)==1 && n){
        scanf("%d%d",&x,&y);
        for(int i=0;i<n;++i) scanf("%d",&a[i]);
        memset(s,0,sizeof(s));
        int S=1<<n;
        for(int i=0;i<S;++i){
            for(int j=0;j<n;++j){
                if(i&(1<<j)){
                    s[i]+=a[j];
                }
            }
        }
        int ans=0;
        if(s[(1<<n)-1]==x*y) ans=DP((1<<n)-1,min(x,y));
        printf("Case %d: %s\n",kase,(ans==0)?"No":"Yes");
        ++kase;
    }
    return 0;
}
发布了180 篇原创文章 · 获赞 3 · 访问量 3469

猜你喜欢

转载自blog.csdn.net/zpf1998/article/details/104890053