北大ACM(POJ1010-STAMPS)

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 }

 

转载于:https://www.cnblogs.com/TYcnblogs/p/poj1010.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值