HDU

来源:互联网 发布:php server 编辑:程序博客网 时间:2024/06/02 17:03

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

题目大意:n个骨头中挑出不超过容量的骨头,求第k大的价值。

解题思路:首先是01背包问题,那么如何处理第k大,dp多开一维用来记录第k大,在每次更新的时候,直接循环把第k大的找出来

AC代码:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 1000 + 5;const int MAXK = 30 + 2;int dp[MAXN][MAXK], val[MAXN], vol[MAXN], a[MAXN], b[MAXN];int main(){    int t;scanf("%d", &t);    while (t--)    {        memset(dp, 0, sizeof(dp));        int n, cap, rangking;        scanf("%d%d%d", &n, &cap, &rangking);        for (int i = 1;i <= n;++i)            scanf("%d", val + i);        for (int i = 1;i <= n;++i)            scanf("%d", vol + i);        for (int i = 1;i <= n;++i)            for (int j = cap;j >= vol[i];--j)            {                for (int k = 1;k <= rangking;++k)                    a[k] = dp[j][k], b[k] = dp[j - vol[i]][k] + val[i];                int x = 1, y = 1, z = 1;                a[rangking + 1] = b[rangking + 1] = -1;                while ((a[x] != -1 || b[y] != -1) && z <= rangking)//归并排序,因为a[],b[]中的元素单调                {                    if (a[x] > b[y])                        dp[j][z] = a[x++];                    else                        dp[j][z] = b[y++];                    if (dp[j][z] != dp[j][z - 1])                        z++;                }            }        printf("%d\n", dp[cap][rangking]);    }    return 0;}
原创粉丝点击