问题
https://vjudge.net/problem/UVA-1099
分析
时间是 O ( x 3 n ) O(x3^n) O(x3n),状态 O ( x 2 n ) O(x2^n) O(x2n).
#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;
}