//LA 4794 状压dp //据说是当年2010年全球总决赛最简单的一道题目 #define _CRT_SECURE_NO_WARNINGS #pragma warning(disable:4996) #include<stdio.h> #include<stdlib.h> #include<istream> #include<vector> #include<math.h> #include<stack> #include<string.h> #include<algorithm> #define mod 10000009 #define maxn 10001 #define long long ll using namespace std; int a[1<<15+1],b[20],n,dp[102][1<<15+1],vis[102][1<<15+1]; //dp第一维表示最短的宽,第二维表示面积状态,一般会表示为三维,长,宽,面积,但复杂度会超标,因此采用如上方式,但要注意的是,如上方式判定最后一块面积时要在最后加一个条件。 int bitcount(int x) { int i,f=0; for(i=0;i<n;i++) { int t=1<<i; if((x&t)!=0) f++; } return f; } int dfs(int l, int sta) { int i, j; if(vis[l][sta]) return dp[l][sta]; vis[l][sta]=true; if(bitcount(sta)==1) return dp[l][sta]=1; for (i = 1;i < sta;i++) { if ((i&sta) == i) { if (a[i] % l == 0) { if (dfs(min(l,(a[sta]-a[i])/l),sta-i) && dfs(min(a[i]/l,l),i)) { return dp[l][sta]=1; } } if (a[i] % ( a[sta] / l) == 0) { int ll = a[sta] / l; if (dfs(min(ll, (a[sta] - a[i]) / ll), sta - i) && dfs(min(a[i] / ll, ll), i)) { return dp[l][sta]=1; } } } } return dp[l][sta]=0; } int main() { //freopen("d:\\in.txt", "r", stdin); int cnt=0; while (~scanf("%d", &n) && n != 0) { cnt++; int i,x,y; memset(a,0,sizeof(a)); memset(vis,false,sizeof(vis)); scanf("%d%d", &x, &y); for (i = 1;i <= n;i++) scanf("%d", &b[i]); int t,all; all = 1 << n; all--; for (i = 1;i <= all;i++) { int sum = 0; for (int j = 0;j < n;j++) { int tem = 1 << j; if ((i&tem) != 0) a[i] += b[j + 1]; } } if (x > y) t = dfs(y, all); else t = dfs(x, all); if(a[all]!=x*y||a[all]%x!=0) //这里要注意一下,假如是 面积4*4,分割为8,会误认为可以,因为最后一步只考虑了是否为一块。 { printf("Case %d: No\n", cnt); continue; } if (t != 0) printf("Case %d: Yes\n", cnt); else printf("Case %d: No\n", cnt); } return 0; }