源代码: #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 ",Ans); } return 0; } /* 背包和物品可以看做二维平面,可以发现,除了特殊情况,1*3的物品最后可以只剩下小于3的空间。 按价值排序,贪心即可。 贪心还真是神奇,虽然不知道怎么证明的。 */