USTC 1351 逆袭

逆袭
Time Limit: 2000ms
Memory Limit: 65536kb
Description
WHZ准备向女神表白,所以他决定学高富帅CJY把女神的淘宝收藏夹里的东西全买了,结果发现收藏夹里的东西又贵又多,毕竟搬砖的钱有限,所以他决定把女神的东西分成4类,每类买一个。现在他需要从每一种东西中选一个来买,并且尽可能的花更多的钱...
Input
第一行输入一个整数T(T<=30),表示测试数据组数。
每一组数据:
第一行1个整数m,表示WHZ的总钱数(0<m<=2*10^9)。
接下来4行,每行第一个数为整数n,后接n个整数a1,a2...an。n表示该类物品的个数,ai表示该商品的价格(0<n<=300,0<ai<=5*10^8)。
Output
如果钱不够4种物品各买一个,输出-1,否则输出最多的花钱数。
Sample Input
2
5
1 2
1 3
1 3
1 2
10
2 1 3
3 5 4 1
3 8 4 1
1 1
Sample Output
-1
10
Source

lym@USTC ACM team


将4个数组经过预处理转化为2个,再用2分


#include<stdio.h>
#include<algorithm>

using namespace std;

int m;
int a[5][500];
int b[2][100000];

int find(int a)
{
	int x=1,y=b[1][0];
	int mid,tmp=y;
	while(x<=y)
	{
		mid=(x+y)/2;
		if(a+b[1][mid]<=m && (a+b[1][mid+1]>m || tmp==mid) )
			return a+b[1][mid];
		if(a+b[1][mid]<=m)
			x=mid+1;
		else
			y=mid-1;
	}
	return -1;
}

int main()
{
	int T,i,j,k,ok;
//	freopen("d:\\in.txt","r",stdin);
	scanf("%d",&T);
	while(T--)
	{
		int tmp;
		scanf("%d",&m);
		for(i=1;i<=4;i++)
		{
			scanf("%d",&a[i][0]);
			for(j=1;j<=a[i][0];j++)
			{
				scanf("%d",&a[i][j]);
			}
		}
		for(k=0;k<2;k++)
		{
			b[k][0]=a[1+2*k][0]*a[2+2*k][0];
			for(i=1;i<=a[1+2*k][0];i++)
			{
				for(j=1;j<=a[2+2*k][0];j++)
				{
					b[k][(i-1)*a[2+2*k][0]+j]=a[1+2*k][i]+a[2+2*k][j];
				}
			}
			sort(b[k]+1,b[k]+a[1+2*k][0]*a[2+2*k][0]+1);
		}
		int max=0;
		ok=0;
		for(i=1;i<=b[0][0];i++)
		{
			tmp=find(b[0][i]);
			if(tmp==-1)
				break;
			ok=1;
			if(tmp>max)
				max=tmp;
		}
		if(ok)
			printf("%d\n",max);
		else
			printf("-1\n");
	}
	return 0;
}


你可能感兴趣的:(USTC 1351 逆袭)