源代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,k1,k2,i1[10001],i2[10001];
bool Rule(int t1,int t2)
{
return t1>t2;
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
scanf("%d%d%d%d",&n,&m,&k1,&k2);
for (int a=1;a<=k1;a++)
scanf("%d",&i1[a]);
for (int a=1;a<=k2;a++)
scanf("%d",&i2[a]);
sort(i1+1,i1+k1+1,Rule);
sort(i2+1,i2+k2+1,Rule);
for (int a=1;a<=k1;a++) //前缀和优化。
i1[a]+=i1[a-1];
for (int a=1;a<=k2;a++)
i2[a]+=i2[a-1];
int Room; //Room表示剩余的空间。
if (n%3==2&&m%3==2&&(n==2||m==2)) //特判。
Room=4;
else
Room=n*m%3;
int Ans=0,Limit=min(k2,(n*m-Room)/3);
for (int a=0;a<=Limit;a++) //贪心。
Ans=max(Ans,i2[a]+i1[min(k1,(n*m-a*3)>>1)]);
printf("%d\n",Ans);
}
return 0;
}
/*
背包和物品可以看做二维平面,可以发现,除了特殊情况,1*3的物品最后可以只剩下小于3的空间。
按价值排序,贪心即可。
贪心还真是神奇,虽然不知道怎么证明的。
*/