/* 01背包第k优解问题 f[i][j][k] 前i个物品体积为j的第k优解 对于每次的ij状态 记下之前的两种状态 i-1 j-w[i] (选i) i-1 j (不选i) 分别k个 然后归并排序并且去重生成ij状态的前k优解 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 1010 using namespace std; int T,n,m,k,c[maxn],v[maxn],f[maxn][100],x[maxn],y[maxn],a,b,z; int init() { int x=0;bool f=0;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} if(f)return -x; return x; } int main() { T=init(); while(T--) { memset(f,0,sizeof(f)); n=init();m=init();k=init(); for(int i=1;i<=n;i++) v[i]=init(); for(int i=1;i<=n;i++) c[i]=init(); for(int i=1;i<=n;i++) { for(int j=m;j>=c[i];j--) { for(int l=1;l<=k;l++) { x[l]=f[j][l]; y[l]=f[j-c[i]][l]+v[i]; } a=b=z=1; x[k+1]=y[k+1]=-1; while(z<=k&&(x[a]!=-1||y[b]!=-1)) { if(x[a]<y[b])f[j][z]=y[b],b++; else f[j][z]=x[a],a++; if(f[j][z]!=f[j][z-1])z++; } } } printf("%d ",f[m][k]); } return 0; }