hdu 2639 Bone Collector II (第K大揹包)

在求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 */
View Code
相關文章
相關標籤/搜索