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?'
':' ');
}

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
", f[v][K-1]);                            //答案是f[v][k-1]
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xingxing1024/p/5002480.html