Topic Links:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem= 3540
Main topic:
Give a long x, a wide y chocolate, and an array of A={A1, A2, ..., an}, and ask if you can get the n block of chocolate,... an area of A1,A2, respectively, after several slices. Each slice can only choose a piece of chocolate, divide it into two halves, for example, 3x4 chocolate after slicing, you can get the area of 6,3,2,1 chocolate respectively.
Problem Solving Ideas:
Suppose to get n blocks of small chocolate, consider the process of slicing, the first slice of chocolate is divided into two parts, the final result of any fast chocolate a[i] either from the first part, or from the second part, that the two parts corresponding to a subset of a. Then enumerate a subset of A0, another a1=a-a0, if you can find a slice of the current chocolate, so that the first part can be divided into A0 corresponding to the small chocolate, the second part is divided into A1 corresponding to the small chocolate, then found a set of legitimate solutions.
Define the DP state as follows, Dp[x][s] (S is a set of binary representations) that indicates the length of the edge is X, and s corresponds to the area/X of the chocolate can be cut into s corresponding set, if it is 1, otherwise 0. Take into account the side length x*y= area, so only one side length is retained, the other side can be calculated.
The method of enumerating subsets in this code is a technique of digital DP.
Reference code:
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5 #defineN 166 7 BOOLf[ the][1<<N];8 BOOLvis[ the][1<<N];9 intA[n], sum[1<<N];Ten intCntbit (intx) One { A intRET =0; - while(x) ret + = x&1, x >>=1; - returnret; the } - - BOOLdpintXintCur//cur The current collection in binary notation - { + if(Vis[x][cur] = =1)returnF[x][cur]; -Vis[x][cur] =1; + BOOL&ans =F[x][cur]; A inty = sum[cur]/x; at if(cntbit (cur) = =1) - { -Vis[x][cur] =1; - returnAns =true; - } - for(intS0 = (cur-1) &cur; S0; S0 = (s0-1) & cur)//methods for enumerating subsets in { - intS1 = cur-S0; to if(sum[s0]%x = =0&& dp (min (x, sum[s0]/x), S0) && dp (min (x, sum[s1]/x), S1)) + returnAns =1; - if(Sum[s0]%y = =0&& dp (min (y, sum[s0]/y), S0) && dp (min (Y, sum[s1]/y), S1)) the returnAns =1; * } $ returnAns =0;Panax Notoginseng } - the intMain () + { A intn, x, y, cas =1; the while(~SCANF ("%d", &N), N) + { -scanf"%d%d", &x, &y); $ for(inti =0; I < n; i++) scanf ("%d", &a[i]); $ -memset (SUM,0,sizeof(sum)); - for(inti =0; I < (1<<N); i++) the for(intj =0; J < N; J + +)if(i& (1<<J)) Sum[i] + =A[j]; - Wuyi intD = (1<<n)-1; the if(Sum[d]! = x*y) - { Wuprintf"Case %d:no\n", cas++); - Continue; About } $ -memset (Vis,0,sizeof(Vis)); - BOOLAns =dp (min (x, y), d); -printf"Case %d:", cas++); APuts (ans?)"Yes":"No"); + } the return 0; -}
UVa 1009 Sharing Chocolate (digital DP)