UVA 12124 UVAlive 3971 Assemble(二分 + 贪心)

时间:2023-03-10 07:52:48
UVA 12124 UVAlive 3971 Assemble(二分 + 贪心)

先从中找出性能最好的那个数,

在用钱比較少的去组合,能组出来就表明答案在mid的右边,反之在左边,

#include<string.h>

#include<map>

#include<stdio.h>

#include<iostream>

#include<algorithm>

using namespace std;

map<string,int> vic;//以字符映射数字

int end,start;

int num;

int m,n;

int sba,sbb;

char name[1000];

int pnum[1005];

struct node{

int v,q;

}p[1005][1005];

bool cmp(node a,node b)

{

return a.v<b.v;

}

int judge(int mid)

{

int sum=0,i,j;

for(i=1;i<num;i++)

{

for(j=0;j<pnum[i];j++)

{

if(p[i][j].q>=mid&&sum+p[i][j].v<m)

{

sum+=p[i][j].v;

break;

}

}

if(j==pnum[i])//质量高了

return 0;

}

return 1;

}

int main()

{

int t;

scanf("%d",&t);

while(t--)

{

vic.clear();//映射

scanf("%d %d\n",&n,&m);

memset(pnum,0,sizeof(pnum));

end=0;

start=0;

num=1;

for(int i=0;i<n;i++)

{

    scanf("%s%*s%d%d",name,&sba,&sbb);

if(end<sbb)

end=sbb;

if(!vic[name])

{

vic[name]=num++;

p[vic[name]][pnum[vic[name]]].v=sba;

p[vic[name]][pnum[vic[name]]++].q=sbb;

}

else

{

p[vic[name]][pnum[vic[name]]].v=sba;

p[vic[name]][pnum[vic[name]]++].q=sbb;

}

}

for(int i=0;i<num;i++)

sort(p[i],p[i]+pnum[i],cmp);

int mid;

while(start<end)

{

mid=(end+start)>>1;

if(judge(mid))

{

    if (start == mid)

                  break;

start=mid;

}

else

end=mid;

}

if(judge(mid+1))

mid++;

printf("%d\n",mid);

}

return 0;

}