Poj 1020
传送门:http://poj.org/problem?id=1020
深搜,dps真的是一个深坑,想哭
填蛋糕,从左往右从下往上,从大的开始,每次要把底层填满再填上面的
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 5 const int MAX=45; 6 int t; 7 int m; 8 int cake[MAX]; 9 int piece[11]; 10 int number; 11 int cakesize; 12 int sum; 13 int halfsize; 14 int overhalf; 15 16 bool dfs(int i){//i:当前填充蛋糕个数 17 int minRow=1; 18 if(i>number){ 19 return true; 20 } 21 for(int j=2;j<=m;j++){ 22 if(cake[j]<cake[minRow]){ 23 minRow=j; 24 } 25 }//找到填充数最小的列 26 for(int k=10;k>=1;k--){ 27 if(!piece[k]){ 28 continue; 29 } 30 if(minRow+k-1<=m&&cake[minRow]+k<=m){ 31 bool flag=true; 32 for(int c=0;c<k;c++){ 33 if(cake[minRow+c]>cake[minRow]){//之前使用了cake[minRow+c]+k>m一直超时,换成这个就好了…… 34 flag=false; 35 break; 36 } 37 } 38 if(flag){ 39 piece[k]--; 40 for(int c=0;c<k;c++){ 41 cake[minRow+c]+=k; 42 } 43 if(dfs(i+1)){ 44 return true; 45 } 46 piece[k]++; 47 for(int c=0;c<k;c++){ 48 cake[minRow+c]-=k; 49 } 50 } 51 } 52 } 53 return false; 54 } 55 56 int main(){ 57 cin>>t; 58 while(t--){ 59 cin>>m; 60 cakesize=m*m; 61 halfsize=m/2; 62 overhalf=0; 63 sum=0; 64 cin>>number; 65 int k; 66 memset(piece,0,sizeof(piece)); 67 for(int i=0;i<number;i++){ 68 cin>>k; 69 piece[k]++; 70 sum+=k*k; 71 if(k>halfsize){ 72 overhalf++; 73 } 74 } 75 if(sum!=cakesize||overhalf>1){ 76 cout<<"HUTUTU!"<<endl; 77 continue; 78 } 79 memset(cake,0,sizeof(cake)); 80 if(dfs(1)){ 81 cout<<"KHOOOOB!"<<endl; 82 } 83 else{ 84 cout<<"HUTUTU!"<<endl; 85 } 86 } 87 }