12124 - Assemble

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=456&problem=3276&mosmsg=Submission+received+with+ID+12193995

题目大意:给定预算金额,和n个电脑配件,要你组装成一台电脑。输入零件类型  名称  价格 和品质因子,要求组装的电脑每个类型的零件都要用到,要求在不超预算的情况下,使买的零件的品质因子和最大,输出买的零件中品质因子最小的。

题目解析:本题即求最小值最大,可以用二分解决,即枚举品质因子,判断和否符合要求。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 1010
#define INF 0xfffffff
typedef struct node
{
        int w,v;        
}node;
node map[MAX][MAX];
char sname[MAX][20];   
int n,b,cnt[MAX],tot;
void set_read(char *type,char *name,int w,int v)
{
     int i,j;
     for (i=0;i<tot;i++)
     {
         if (strcmp(sname[i],type)==0)
         {
            map[i][cnt[i]].w=w;
            map[i][cnt[i]].v=v;
            cnt[i]++;
            return ;                             
         }    
     }
     strcpy(sname[tot],type);
     map[tot][cnt[tot]].w=w;
     map[tot][cnt[tot]].v=v;
     cnt[tot]++;
     tot++;
     return ;
}
int max(int x,int y)
{
    return x>y? x:y;    
}
int min(int x,int y)
{
    return x<y?x:y;
}
int ok(int x)
{
    int i,j;
    int sum=0;
    for (i=0;i<tot;i++)
    {
        int temp=INF;
        for (j=0;j<cnt[i];j++)
        {
            if (map[i][j].v>=x)
            {
               temp=min(temp,map[i][j].w); 
            }     
        }
        if (temp==INF)                    
           return 0;
        sum+=temp;
        if (sum>b)
           return 0;   
    }
    return 1;
}
int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
          int i,j,w,v,maxv=0;
          char name[20],type[20];
          tot=0;
          memset(cnt,0,sizeof(cnt));
          scanf("%d%d",&n,&b);
          for (i=0;i<n;i++)
          {
              scanf("%s%s%d%d",type,name,&w,&v);
              set_read(type,name,w,v);  
              maxv=max(v,maxv);  
          }
          /*printf("%d\n",tot);
          for (i=0;i<tot;i++)
          {
              //printf("%d ",cnt[i]);
              for (j=0;j<cnt[i];j++)
              {
                  printf("(%d %d) ",map[i][j].w,map[i][j].v);    
              }
              printf("\n");
          }*/
          int L=0,R=maxv;
          while (L<R)
          {
                int M=L+(R-L+1)/2;
                if (ok(M))
                   L=M;
                else
                   R=M-1; 
          }
          printf("%d\n",L);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值