Question address: http://uva.onlinejudge.org/index.php? Option = com_onlinejudge & Itemid = 8 & page = show_problem & problem = 3540
Question meaning:
Here is a piece of x * y chocolate.
Ask if you can divide into N small chocolate blocks of AI size
Solution:
We can use F [x] [s] to indicate whether a small edge can be divided into X and the set is S.
There are two types of Slice: cross cutting and vertical cutting.
Cross-cutting is X, vertical cutting is Y, and can be split into two subsets and searched by memory
For those whose x * Y is not equal to sum [s], we can directly do not calculate, because it cannot meet the requirements and is not necessary for calculation.
The code below:
# Include <cstdio >#include <cstring >#include <algorithm> using namespace STD; const int maxn = 16; const int Maxs = 1 <maxn; const int Maxx = 110; int A [maxn]; int f [Maxx] [Maxs]; bool vis [Maxx] [Maxs]; int sum [Maxs]; int X, Y, N; int all; int bitcount (int x) {return x = 0? 0: bitcount (x> 1) + (X & 1);} int dp (int s, int X) {If (vis [x] [s]) return f [x] [s]; vis [x] [s] = 1; Int & Ans = f [x] [s]; If (bitcount (s) = 1) return ans = 1; int y = sum [s]/X; // enumerated subset S0 for (INT S0 = (S-1) & S; S0; s0 = (S0-1) & S) {int S2 = S-S0; If (sum [S0] % x = 0 & dp (S0, min (X, sum [S0]/X) & dp (S2, min (x, sum [s2]/X) return ans = 1; if (sum [S0] % Y = 0 & dp (S0, min (Y, sum [S0]/y) & dp (S2, min (Y, sum [s2]/y) return ans = 1;} retur N ans = 0;} int main () {int CA = 1; while (~ Scanf ("% d", & N) {memset (sum, 0, sizeof (SUM); scanf ("% d", & X, & Y); For (INT I = 0; I <n; I ++) scanf ("% d", & A [I]); For (INT S = 0; S <(1 <n); s ++) {for (INT I = 0; I <n; I ++) {If (S & (1 <I) sum [s] + = A [I] ;}} all = (1 <n)-1; memset (VIS, false, sizeof (VIS); int ans; If (sum [all]! = X * Y | sum [all] % x! = 0) ans = 0; else ans = dp (all, min (x, y); printf ("case % d: % s \ n", CA ++, ans? "Yes": "no");} return 0 ;}