HDU2639 第k小01背包 xingxing在努力

    这个题目是求解第k小01背包, 我们只需要再多加一维表示容量为j时的价值即可。。代码里面用了归并排序的思想来求解f[j][k], 代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
int f[1000+10][35];
int A[35], B[35];     //A选  B不选
int W[100+10], V[100+10];
int N, v, K;

void print(int a[], int s, int e)
{
    for(int i=s; i<=e; i++)
        printf("%d%c", a[i], i==e?‘\n‘:‘ ‘);
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d%d", &N, &v, &K);
        for(int i=1; i<=N; i++)
            scanf("%d", &V[i]);
        for(int i=1; i<=N; i++)
        {
            scanf("%d", &W[i]);
        }
        memset(f, 0, sizeof(f));
        for(int i=1; i<=N; i++)
        {
            for(int j=v; j>=0; j--)
            {
                int Aln=0, Bln=0;
                for(int kk=0; kk<K; kk++)
                {
                    if(j >= W[i])
                        A[Aln++] = f[j-W[i]][kk]+V[i];    //选
                    B[Bln++] = f[j][kk];                  //不选
                }
                //printf("A: ");
                //print(A, 0, Aln-1);
                //printf("B: ");
                //print(B, 0, Bln-1);
                int An=0, Bn=0;
                int c = 0;
                while(c < K && An<Aln && Bn<Bln)
                {
                    if(A[An] > B[Bn])
                        f[j][c] = A[An++];
                    else
                        f[j][c] = B[Bn++];
                    if(c==0 || (c>0&&f[j][c]!=f[j][c-1])) c++;
                }
                while(c < K && An<Aln)
                    f[j][c++] = A[An++];
                while(c<K && Bn<Bln)
                    f[j][c++] = B[Bn++];
                //printf("unite: ");
                //print(f[j], 0, K-1);
            }
        }
        printf("%d\n", f[v][K-1]);                            //答案是f[v][k-1]
    }
    return 0;
}
时间: 2024-10-13 00:11:07

HDU2639 第k小01背包 xingxing在努力的相关文章

POJ2923 状态压缩01背包 xingxing在努力

这道题算是很经典的状态压缩01背包了, 题意是有一个人要用两辆小汽车搬家, 每辆小汽车都有一个最大载重量, 现在有一些要搬的家具, 告诉你这些家具的重量, 问最少几次能将这些家具搬完(每次两辆汽车必须出动, 即使有一辆车什么都没有装)? 物品个数不超过10,根据经验一般有10存在的话都要带点暴力的色彩, 那么这道题就是先要预处理所有一次搬走的家具的集合, 然后就将其转化成了01背包的问假设d[i][j]是前i个家具中搬走了j(集合)家具所需要的最少次数那么d[i][j] = min(d[i-1]

HDU2602 01背包 xingxing在努力

很经典的01背包, 假设f(i, j)是将i个物品放入容量为j的背包, 那么可得到如下递推式f(i, j) = max(f(i-1, j) , f(i-1, j-c[i])+v[i]))....实现的话有两种方式, 一种是直接用二维数组实现, 另外一种是滚动数组, 不过要注意的是, 如果题意是让这些物品恰好装满背包,那么f(0, 0)为0其他为无穷大, 如果没必要恰好装满那就全部初始化为0: 代码如下: #include <cstdio> #include <cstring> #i

第K大01背包

其实这个问题,真的挺好想的,但是我咋想了那么久呢~~ 很好理解,第K大01背包一定基于01背包,dp数组也很容易的想到由dp[V]  ---->   dp[V][K],来表示背包容量是V时候的第K大背包 然后就是状态转移方程了,多写一写,你也能手推出来的,不能被吓到 dp[V][1] = max_第一大(dp[v][1],dp[v-w][1]+vi) dp[V][2] = max_第二大数(dp[v][1],dp[v-w][1]+vi,dp[v][2],dp[v-w][2]+vi) =  max

[HDOJ2639]Bone Collector II(第k优01背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639 题意:求01背包的第k优解 dp(i, j)表示容量为j时的i优解 对于第二维的操作和01背包几乎一样,只是我们只需要关注每一次取的前k大个即可. 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <cli

POJ1787 完全背包 xingxing在努力

这道题的意思是给你1 5 10 25 的硬币c1 c2 c3 c4枚, 求出一个方案使硬币个数最多, 且恰好是p..给完全背包加几个状态即可..代码如下: WA点: 可能看完动漫时间有点晚记得把题目终止输入条件判错了 2:used[j-w[i]]<num[i]写错成used[j-w[i]]+1<num[i],罪过罪过: #include <cstdio> #include <cstring> #include <algorithm> using namesp

hdu1864 最大报销额(01背包)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1864 Problem Description 现有一笔经费能够报销一定额度的发票.同意报销的发票类型包含买图书(A类).文具(B类).差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元.现请你编敲代码,在给出的一堆发票中找出能够报销的.不超过给定额度的最大报销额. Input

【HDU2639】Bone Collector II(01背包第k优解)

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2948    Accepted Submission(s): 1526 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took pa

HDU2639(01背包第K大)

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3437    Accepted Submission(s): 1773 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took par

01背包之求第K优解——Bone Collector II

http://acm.hdu.edu.cn/showproblem.php?pid=2639 题目大意是,往背包里赛骨头,求第K优解,在普通01背包的基础上,增加一维空间,那么F[i,v,k]可以理解为前i个物品,放入容量v的背包时,第K优解的值.时间复杂度为O(NVK). Talk is cheap. 看代码吧. import java.util.Scanner; public class BoneCollector { public static void main(String[] sur