HDU2639Bone Collector II(01背包变形)

01背包,求第k大。

以前看k短路的时候看过代码以为懂了 = =结果还是跑去看了别人的代码才会。果然要自己写一遍才行啊 0.0难得1A。。

每次把可能的2k种求出来,求前k个。注意要不一样的k个数。。

/**************************************************************
Problem : 2639 ( Bone Collector II )     Judge Status : Accepted
RunId : 15212165    Language : G++    Author : G_lory
Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta
***************************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

//N <= 100 , V <= 1000 , K <= 30

const int MAXN = 105;
const int MAXV = 1005;
const int MAXK = 35;

int val[MAXN];
int vol[MAXN];

int dp[MAXV][MAXK];

int a[MAXK], b[MAXK];

int main()
{
    int n, v, k;
    int t;
    cin >> t;
    while (t--)
    {
        memset(dp, 0, sizeof dp);

        cin >> n >> v >> k;
        for (int i = 0; i < n; ++i)
            cin >> val[i];
        for (int i = 0; i < n; ++i)
            cin >> vol[i];

        for (int i = 0; i < n; ++i)
        {
            for (int j = v; j >= vol[i]; --j)
            {
                for (int q = 0; q < k; ++q)
                {
                    a[q] = dp[j][q];
                    b[q] = dp[j - vol[i]][q] + val[i];
                }

                int ic = 0, jc = 0;
                int ck = 0;

                while (ic < k && jc < k && ck < k)
                {
                    if (a[ic] < b[jc])
                    {
                        if (ck == 0 || b[jc] < dp[j][ck - 1])
                            dp[j][ck++] = b[jc];
                        jc++;
                    }
                    else
                    {
                        if (ck == 0 || a[ic] < dp[j][ck - 1])
                            dp[j][ck++] = a[ic];
                        ic++;
                    }
                }

                while (ic < k && ck < k)
                {
                    if (ck == 0 || a[ic] < dp[j][ck - 1])
                        dp[j][ck++] = a[ic];
                    ic++;
                }

                while (jc < k && ck < k)
                {
                    if (ck == 0 || b[jc] < dp[j][ck - 1])
                        dp[j][ck++] = b[jc];
                    jc++;
                }
            }
        }

        cout << dp[v][k - 1] << endl;
    }
    return 0;
}

  

posted @ 2015-10-23 12:31  我不吃饼干呀  阅读(190)  评论(0编辑  收藏  举报