uestc oj 1484 STAMPS

    首先说明下:咱们oj上的数据就是给力,完败poj在poj上我明明写错了还是能过,显然数据太水,还是咱们oj好。
    本题利用深度优先搜索完成
    在搜索到每一个数据时分五个方向向下递归神搜分别是0,1,2,3,4 五个方向
    同样设置一个temp 一个ans  找到忧解之后与假定最优解进行比较最后确定最优解
    在邮票张数大于4或者说在搜素的种类数已经超过总数时return
    还有一个小优化就是在读入数据时注意的问题就是一旦读入的数据出现4个相同值以上时就不再读入 因为再度入也没有了意义

    还有就是数据看似是有序的但是实际上并没有说明 还是要自己排序的

其实这个题目有一个更优秀的解法(不如说是更懒的)直接4个for循环就可以了

回来贴出来看看

题目大意

给你一些邮票的面值,然后给你一些顾客给出的价钱,求出邮票的组合来满足每一位顾客,要求是最多四张邮票,每张可以用多次(其实最多也就四次,因为要求最多四张,否则就是none)。

如:邮票面值1 2 3 0;0代表这行结束

顾客的需求:7 4 0

 

结果:

7 (3): 1 1 2 3

4 (2): 1 3

解释一下:

由于每次有多种组合,那么如何取结果呢?

如果这些组合都能满足用户的的需求,那么

1.选种类最多的

2.如果种类相同,选总数最多的

3.如果总数相同,选邮票值组合最大值最大的那一组

4.如果连最大值也相同,那么就是tie

5。如果没有这样的组合,也就是不能用4张以内的邮票满足顾客,那么就是none

输出格式,第一个是总价值,括号里面的是邮票的种类,后面是相应的值。




#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int type[550];
int req[550];
int x;
int num,size;
int flag;
struct node
{
   int type_num;
   int stamp_num;
   int max;
   int st[550];
};
node temp,ans;


void init()
{
    int i;
    flag = 0;
    temp.max = 0;
    temp.stamp_num = 0;
    temp.type_num = 0;
    for(i=0;i<26;i++)
    temp.st[i]=0;


    ans.max = 0;
    ans.stamp_num = 0;
    ans.type_num = 0;
    for(i = 0;i<26;i++)
    ans.st[i]=0;
}


void cmp()
{
   
     if(temp.type_num>ans.type_num)
     {
        
         ans = temp;
         flag = 1;
     }
     else if(temp.type_num == ans.type_num)
     {


         if(temp.stamp_num<ans.stamp_num)
         {
            
             ans = temp;
             flag = 1;
         }
         else if(temp.stamp_num == ans.stamp_num)
         {
             if (temp.max>ans.max)
            {
               
                ans = temp;
                flag = 1;
            }
         else if(temp.max == ans.max)
            {


            
               flag++;}
         }


     }
}
void dfs(int i, int now_num, int now_sum,int req)
{
     if(now_num > 4) return;
     if(now_sum ==req)
     {
        temp.stamp_num = now_num;
        temp.type_num = 0;
        temp.max = 0;
        for(int ii = 0;ii<size;ii++)
        {
            if(temp.st[ii])
            {
              temp.type_num++;
              if(type[ii]>temp.max)
              temp.max = type[ii];
            }


        }
        cmp();
        return;
     }
     if(i>=size||now_sum>req) return;
     for(int iii=0;iii<=4;iii++)
     {
         temp.st[i]+=iii;
         dfs(i+1,now_num+iii,now_sum+type[i]*iii,req);
         temp.st[i]-=iii;
     }
}
void output(int req)
{
    printf("%d ",req);
    if(flag==0)
    printf("---- none\n");
    else if(flag ==1)
    {
       printf("(%d):",ans.type_num);
       for(int i=0;i<size;i++)
       {
           if(ans.st[i]>0)
           {
               for(int j=0;j<ans.st[i];j++)
                 printf(" %d",type[i]);
           }
       }
       printf("\n");
    }
    else
    printf("(%d): tie\n",ans.type_num);
}


int main()
{
   //freopen("1.txt","r",stdin);
    while(scanf("%d",&x)!=EOF)
    {
        type[0]=x;
        size = 1;
        while(scanf("%d",&x)==1&&x)
        {
           int count = 0;
           for(int i =0;i<size;i++)
           {
               if(x ==type[i])
               count++;
           }
           if(count>4) continue;
           else type[size++]=x;
        }
		sort(type,type+size);
        num = 0;
        while(scanf("%d",&x)==1&&x)
        {
            req[num++]=x;
        }
        
        int h=0;
        while(h<num)
        {
            init();
            dfs(0,0,0,req[h]);
            output(req[h]);
            h++;
        }
    }
}
 				 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值