HDU

传送门

题意:it will be a strictly decreasing sequence from the 1st maximum , 2nd maximum .. to the K-th maximum.  If the total number of different values is less than K,just ouput 0.

输入:T组数据 体积V 要求的K    N , V, K(N <= 100 , V <= 1000 , K <= 30)

  各项价值

  各项体积

定义dp[i][j][k]为利用前i个和体积j能获得的不重复的第K大值。类似于01背包,可以用二维的dp[j][k]去存储信息。当取第i个物品时,枚举取与不取,得到体积j下的2k种情况,选择其中的k种更新答案即可。就像我有两个数列,要求第K大值,只要分别得知两个数列里的前K个值即可

复杂度是O(NVK)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #define INF 0x3f3f3f3f
 6 #define MOD 1000000007
 7 using namespace std;
 8 typedef long long LL;
 9 
10 const int maxn = 1e2 + 10;
11 const int maxv = 1e3 + 10;
12 const int maxk = 35;
13 
14 int dp[maxv][maxk];
15 int slt[maxk], no_slt[maxk];
16 int val[maxn], vol[maxn];
17 
18 int N, V, K;
19 
20 int main(int argc, const char * argv[]) {
21     int T; scanf("%d", &T);
22     while (T--) {
23         memset(dp, 0, sizeof(dp));
24         scanf("%d%d%d", &N, &V, &K);
25         for (int i = 0; i < N; i++) scanf("%d", &val[i]);
26         for (int i = 0; i < N; i++) scanf("%d", &vol[i]);
27         for (int i = 0; i < N; i++) {
28             for (int j = V; j >= vol[i]; j--) {
29                 for (int k = 1; k <= K; k++) {
30                     slt[k] = dp[j - vol[i]][k] + val[i];
31                     no_slt[k] = dp[j][k];
32                 }
33                 slt[K + 1] = -1; no_slt[K + 1] = -1;
34                 int p1 = 1, p2 = 1, p3 = 1;
35                 while (p1 <= K && (slt[p2] != -1 || no_slt[p3] != -1)) {
36                     if (slt[p2] > no_slt[p3]) {
37                         dp[j][p1] = slt[p2++];
38                     } else {
39                         dp[j][p1] = no_slt[p3++];
40                     }
41                     if (dp[j][p1] != dp[j][p1 - 1])
42                         p1++;
43                 }
44                 
45             }
46         }
47         printf("%d
", dp[V][K]);
48     }
49     return 0;
50 }
原文地址:https://www.cnblogs.com/xFANx/p/7414266.html