Source: http://blog.csdn.net/lyy289065406/article/details/6683250
Approximate test instructions:
There is a side long for boxsize square big cake, now give n block different size square small cake edge length, ask whether can the big cake according to exactly cut for this n piece of small cake, require each small cake must be whole block.
Problem Solving Ideas:
A skilled DFS
You can think of a big cake as a cake box and then put a small cake in it.
The following principles apply when loading cakes:
Bottom up, from left to right;
That is, first install the bottom of the box, and then continue to the upper deck, and each layer is placed on the left side of the cake;
Big cake priority, because the small cake flexibility is higher.
As long as the problem to change to the above questions, I would like to deep search more familiar with the students will immediately get ideas, this is just a very simple DFS ideas.
But the crux of the problem is not how to go to DFS, but after each put a cake, how to mark the box has placed a cake position?
Should be "Tagged by column". Not only the box as a plurality of 1*1, but also the small cake as multiple 1*1 units, the establishment of a one-dimensional array col[boxsize], each into a cake, then to record the number of each column of the grid is filled.
For example in the 2nd to 4th column put a size=3 small cake, then col[2]+=3, Col[3]+=3, col[4]+=3. A reunion asked, why do not count? What happens to the bottom part of the cake when the cake is placed? This situation will not occur, because the current DFS follows the bottom of the first full principle, if there is dangling, will backtrack.
#include <iostream> #include <cstring>using namespace Std;int boxsize; Box size int n;//total number of cakes int sizenum[11];//number of cakes of various sizes int COL[41];//COL[I] Record column I was populated the number of squares bool DFS (int fillnum)//The number of cakes placed in the box {if (fillnum==n) return true; Look for the columns that are filled with the fewest squares, and left precedence int min=50; int prow; for (int i=1; i<=boxsize; i++) {if (Min>col[i]) {min=col[i]; Prow=i; }}//Enumerate various sizes of cakes from the bottom to the box for (int size=10; size>=1; size--) {if (! Sizenum[size]) continue; Check if the size of the cake is placed in the box when it crosses the vertical and horizontal if (boxsize-col[prow]>=size && boxsize-prow+1>=size) { Check the box from column prow to column prow+size-1, the width of the total size column wide//whether the remaining space in each column is enough to be placed in the height of the cake int wide=0 for size; for (int r=prow; r<=prow+size-1; r++) {if (Col[r]<=col[prow])//Compare the number of "fills" of each column { wide++; Continue } break; } if (wide>=size) {int r; Put the size of the cake sizenum[size]--; for (R=prow; r<=prow+size-1; r++) col[r]+=size; if (DFS (fillnum+1)) return true; Backtracking sizenum[size]++; for (R=prow; r<=prow+size-1; r++) col[r]-=size; }}} return false;} int main () {int t; cin>>t; while (t--) {memset (sizenum, 0, sizeof (sizenum)); memset (col, 0, sizeof (COL)); cin>>boxsize>>n; int cnt=0;//Records size> (BOXSIZE/2) The number of cakes int area=0;//calculates the sum of the area of all cakes for (int i=0; i<n; i++) { int size; cin>>size; Area+=size*size; sizenum[size]++; if (SIZE>BOXSIZE/2) cnt++; } if (cnt>1| | area!=boxsize*boxsize) {cout<< "hututu!" <<endl; Continue } if (DFS (0)) cout<< "khoooob!" <<endl; else cout<< "hututu!" <<endl; } return 0;}
POJ 1020 Anniversary Cake (DFS)