逆袭
Time Limit: 2000ms
Memory Limit: 65536kb
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;
}