zoukankan      html  css  js  c++  java
  • HDU2639 Bone Collector II 题解 0-1背包的严格第k优解

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639

    题目大意:给出一行价值,一行体积,让你在v体积的范围内找出第k大的值.......(注意,不要 和它的第一题混起来,它第一行是价值,再是体积)

    思路:首先dp[i][j]代表的是在体积为i的时候第j优解为 dp[i][j] ......那么,我们就可以这样思考,i 对应体积,那么如果只是一维的 dp[i],代表的应该是体积为 i 时的最大值,那么同理,dp[i][1] 代表的是体积为 i 时的最大值,那么我们就可以退出两种动态,dp[i][m],dp[i-s[i][0]][m]+s[i][1].....然后把这两种状态开个两个数组分别保存起来,再合并出体积为i时的前k优解......依次后推,直到dp[v][k].......

    具体实现的时候,我令 (f[i]) 为一个 set 集合,这样处理的话方面一些(然而也很麻烦)。

    示例代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 101, maxv = 1001;
    int T, n, V, K, c[maxn], v[maxn];
    set<int> f[maxv];
    void pack(int c, int v) {
        for (int i = V; i >= c; i --) {
            f[i].insert(v);
            for (set<int>::iterator it = f[i-c].begin(); it != f[i-c].end(); it ++) {
                f[i].insert((*it) + v);
            }
            int sz = f[i].size();
            while (sz > K) {
                f[i].erase(f[i].begin());
                sz --;
            }
        }
    }
    int main() {
        cin >> T;
        while (T --) {
            cin >> n >> V >> K;
            for (int i = 0; i <= V; i ++) f[i].clear();
            f[0].insert(0);
            for (int i = 0; i < n; i ++) cin >> v[i];
            for (int i = 0; i < n; i ++) cin >> c[i];
            for (int i = 0; i < n; i ++) pack(c[i], v[i]);
            if (f[V].size() < K) puts("0");
            else {
                set<int>::iterator it = f[V].end();
                for (int i = 0; i < K; i ++) it --;
                cout << (*it) << endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Language Integrated Query
    为什么说 LINQ 要胜过 SQL
    LINQ(Language Integrated Query)
    Rx (Reactive Extensions)介绍
    ReactiveX Operators
    ReactiveX
    给 iOS 开发者的 RxSwift(一)
    The features of Swift
    RxSwift源码与模式分析一:基本类
    智力
  • 原文地址:https://www.cnblogs.com/quanjun/p/13640072.html
Copyright © 2011-2022 走看看