Question:http://poj.org/problem?id=1010
问题点:DFS、剪枝。
1 Memory: 220K Time: 32MS 2 Language: C++ Result: Accepted 3 4 #include <iostream> 5 using namespace std; 6 7 #define MAX_STAMP_TYPE 100 8 int stamp[MAX_STAMP_TYPE]; 9 bool tie,none; 10 int now[4],ans[4];//记录stamp的index 11 int max_stamp;//记录最大邮票 12 int getInfo(int sta[]){ 13 int tmp_a,tmp_b,tmp_c; 14 tmp_a=1; 15 tmp_b=1; 16 tmp_c=sta[0]; 17 for(int i=1;i<4 && sta[i]>0;i++) 18 { 19 if(sta[i-1]!=sta[i]) tmp_a++;//取种类数 千位 20 tmp_b++;//取总张数 百位 21 tmp_c=sta[i-1]>sta[i]?sta[i-1]:sta[i];//取最大值 十位和个位 22 } 23 return tmp_a*1000+(10-tmp_b)*100+tmp_c; 24 } 25 void compare(){ 26 none=false;//只要有结果,none就置为false 27 int nowInfo=getInfo(now); 28 int ansInfo=getInfo(ans); 29 char r=nowInfo>ansInfo?'g':(nowInfo<ansInfo?'l':'e');//g:出现更优解 l:不如现有解 e:tie 30 if(r=='g'){//如果出现更优解,将now中的数据复制到ans中保存 31 memcpy(ans,now,sizeof(now)); 32 tie=false; 33 }else if(r=='e'){ 34 tie=true; 35 } 36 return; 37 } 38 void dfs(int num,int cnt){ 39 if(num==0){//剩余数为0,即为解的出现条件 40 compare(); 41 return; 42 }else if(cnt>=4){//邮票数不能大于4张 43 return; 44 }else if(num<0){//剩余需分配数不能小于0 45 return; 46 }else if(num>max_stamp*(4-cnt)){ 47 return; 48 } 49 for(int i=(cnt>0?now[cnt-1]:1);i<=stamp[0];i++) 50 { 51 now[cnt]=i; 52 dfs(num-stamp[i],cnt+1); 53 now[cnt]=0; 54 } 55 } 56 int main() 57 { 58 do{ 59 int tmp,i=1; 60 max_stamp=0; 61 memset(stamp,0,sizeof(stamp)); 62 while(cin>>tmp && tmp!=0){ 63 stamp[i++]=tmp; 64 max_stamp=max_stamp>tmp?max_stamp:tmp; 65 } 66 stamp[0]=i-1;//记录邮票种类数 67 while(cin>>tmp && tmp!=0){ 68 tie=false; 69 none=true; 70 memset(now,0,sizeof(now)); 71 memset(ans,0,sizeof(ans)); 72 dfs(tmp,0); 73 if(tie){ 74 cout<<tmp<<" ("<<getInfo(ans)/1000<<"): "<<"tie"<<endl; 75 }else if(none){ 76 cout<<tmp<<" ---- none"<<endl; 77 }else{ 78 cout<<tmp<<" ("<<getInfo(ans)/1000<<"):"; 79 for(int i=0;i<4 && ans[i]>0;i++){ 80 cout<<" "<<stamp[ans[i]]; 81 } 82 cout<<endl; 83 } 84 } 85 }while(getchar()!=EOF); 86 return 0; 87 }