在求dp[i][j]的最優值的時候,咱們比較了兩個值的大小,一個是dp[i][j],一個是dp[i][j-b[i]]+a[i],以前咱們直接拋棄掉其中一個,留下另外一個就是dp[i][j],如今咱們不將其拋棄,而是將其記錄。準確的說咱們之前比較dp[i][j]和dp[i][j-b[i]]+a[i],從中求出第一名,如今咱們比較的是dp[i][j][1...K]和dp[i][j-b[i]][1...k]+a[i],從中求出前K名。數組
思路:分別記錄 dp[i][j] 中前K個解,和 dp[i][j-b[i]]+a[i] 中前K個解,那麼從兩個最有K個解中找出前K個解,這樣就獲得要求的第K個最優解。ide
注意:由於題目認爲若是兩個值相同,不管組合方式如何,都認爲是一種狀況,因此維護數組是要注意去掉值相同的。spa
1 #include<stdio.h> 2 #include<string.h> 3 int a[105],c[105],b[105],d[105],f[1005][35]; 4 int main() 5 { 6 int t,n,V,K; 7 int i,j,tt; 8 scanf("%d",&t); 9 while(t--) 10 { 11 scanf("%d%d%d",&n,&V,&K); 12 for(i=1;i<=n;i++) 13 scanf("%d",&a[i]); 14 for(i=1;i<=n;i++) 15 scanf("%d",&c[i]); 16 memset(f,0,sizeof(f)); 17 for(i=1;i<=n;i++) 18 { 19 for(j=V;j>=c[i];j--) 20 { 21 for(tt=1;tt<=K;tt++) 22 { 23 b[tt]=f[j][tt]; 24 d[tt]=f[j-c[i]][tt]+a[i]; 25 } 26 b[tt]=d[tt]=-1; 27 int x,y,z; 28 x=y=z=1; 29 while(z<=K&&(y<=K||x<=K)) 30 { 31 if(b[x]>d[y]) 32 f[j][z]=b[x++]; 33 else 34 f[j][z]=d[y++]; 35 if(f[j][z]!=f[j][z-1]) 36 z++; 37 } 38 } 39 } 40 printf("%d\n",f[V][K]); 41 } 42 return 0; 43 } 44 /* 45 3 46 5 10 2 47 1 2 3 4 5 48 5 4 3 2 1 49 5 10 12 50 1 2 3 4 5 51 5 4 3 2 1 52 5 10 16 53 1 2 3 4 5 54 5 4 3 2 1 55 */