二分搜索加贪心。
一般最小值最大化都可以这样做。
有一个地方没注意,导致无脑tle多次:部件的种类不一定是8种,也不一定是题目中的名字。。。tmd那这还算是电脑吗。。。还有一种算中点的方法:front+(rear-front+1)/2
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 1010
#define KIND 1000
using namespace std;
struct node
{
int price,quality;
bool operator <(node other)
{
if(price<other.price)
return 1;
return 0;
}
}nod[KIND][MAX];
int all[KIND];
char map[KIND][40];
int main()
{
int t,n,b,i,j,aa,bb,front,rear,mid,money,help,kind;
char input[40],input1[40];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&b);
getchar();
kind=0;
memset(all,0,KIND*4);
front=2000000000,rear=-1;
for(i=0;i<n;i++)
{
scanf("%s",input);
for(j=0;j<kind;j++)
{
if(!strcmp(input,map[j]))
{
scanf("%s",input1);
scanf("%d %d",&aa,&bb);
getchar();
//if(bb<front)
// front=bb;
if(bb>rear)
rear=bb;
nod[j][all[j]].price=aa,nod[j][all[j]++].quality=bb;
break;
}
}
if(j==kind)
{
strcpy(map[kind],input);
scanf("%s",input1);
scanf("%d %d",&aa,&bb);
getchar();
//if(bb<front)
// front=bb;
if(bb>rear)
rear=bb;
nod[kind][all[kind]].price=aa,nod[kind][all[kind]++].quality=bb;
kind++;
}
}
rear++,front=0;
for(i=0;i<kind;i++)
sort(nod[i],nod[i]+all[i]);
//printf("%d %d",front,rear);
while(front+1<rear)
{
//printf("a");
money=0;
mid=(rear+front)/2;
for(i=0;i<kind;i++)
{
for(j=0;j<all[i];j++)
{
if(nod[i][j].quality>=mid)
{
//if(nod[i][j].price<help)
help=nod[i][j].price;
break;
}
}
if(j==all[i]||money>b)
{
rear=mid;
goto next;
}
money+=help;
}
if(money<=b)
front=mid;
else
rear=mid;
next:{}
}
printf("%d\n",front);
}
return 0;
}