zoukankan      html  css  js  c++  java
  • 01背包(求前一个的最大价值-->求前K个的最大价值) 之 hdu 2639

    //  [7/21/2014 Sjm]
    /*
    此题我想的思路错了,情况考虑漏了。。。
    解法是由 求前一个的最大价值-->求前K个的最大价值 的转化。

    求前一个最大价值:
      dp[i][j] = max(dp[i-1][j], dp[i-1][j-C[i]] + W[i])
    求前K个的最大价值
      同样,dp[i][j]的前 k 个最大价值,是依赖于 dp[i-1][j] 的前 k 个最大价值和 dp[i-1][j-C[i]] 的前 k 个最大价值所求得的。

      由此考虑了所有情况,求出了答案。

    */
     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <cstring>
     6 using namespace std;
     7 const int MAX = 100005;
     8 const int MAX_N = 105;
     9 const int MAX_K = 35;
    10 int N, V, K;
    11 int arr[MAX_N][2], dp[MAX][MAX_K];
    12 int tep1[MAX_K], tep2[MAX_K];
    13 
    14 int Solve() {
    15     memset(dp, 0, sizeof(dp));
    16     for (int i = 1; i <= N; ++i) {
    17         for (int j = V; j >= arr[i][1]; --j) { 
    18             for (int k = 1; k <= K; ++k) {
    19                 // 注意:经过此循环,tep1[], tep2[]均是递减排列的。(根据01背包的原理)
    20                 tep1[k] = dp[j - arr[i][1]][k] + arr[i][0];
    21                 tep2[k] = dp[j][k];
    22             }
    23             tep1[K + 1] = tep2[K + 1] = -1;
    24             int pos1 = 1, pos2 = 1;
    25             for (int k = 1; (pos1 <= K || pos2 <= K)&&k <= K;) {
    26                 if (tep1[pos1] > tep2[pos2]) { dp[j][k] = tep1[pos1++]; }
    27                 else { dp[j][k] = tep2[pos2++]; }
    28                 if (dp[j][k] != dp[j][k - 1]) {
    29                     ++k;
    30                 }
    31             }
    32         }
    33     }
    34     return dp[V][K];
    35 }
    36 
    37 int main()
    38 {
    39     //freopen("input.txt", "r", stdin);
    40     //freopen("output.txt", "w", stdout);
    41     int T;
    42     scanf("%d", &T);
    43     while (T--) {
    44         scanf("%d %d %d", &N, &V, &K);
    45         for (int i = 1; i <= N; ++i) {
    46             scanf("%d", &arr[i][0]);
    47         }
    48         for (int i = 1; i <= N; ++i) {
    49             scanf("%d", &arr[i][1]);
    50         }
    51         printf("%d
    ", Solve());
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    C++设计模式之享元模式
    C++设计模式之中介者模式
    C++设计模式之职责链模式
    C++设计模式之命令模式
    C++设计模式之桥接模式
    C++设计模式之单例模式
    C++设计模式之组合模式
    C++设计模式之备忘录模式
    C++设计模式之适配器模式
    操作系统(4)实验0——准备知识、基本内联汇编、扩展内联汇编
  • 原文地址:https://www.cnblogs.com/shijianming/p/4140824.html
Copyright © 2011-2022 走看看