HDU2639 Bone Collector II(dp求第K优解)

/*
HDU  2639
求01背包的第k大解。
合并两个有序序列
*/
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN=110;
int dp[1010][50];//dp[i][j]表示容量为i,第j大的值
int value[MAXN];
int weight[MAXN];
int a[50];
int b[50];
int N,V,K;
void DP()
{
    memset(dp,0,sizeof(dp));
    for(int i=0;i<N;i++)
       for(int j=V;j>=value[i];j--)
       {
           for(int k=1;k<=K;k++)
           {
               a[k]=dp[j][k];
               b[k]=dp[j-value[i]][k]+weight[i];
           }
           int x,y,z;
           x=y=z=1;
           a[K+1]=b[K+1]=-1;//这个一定要
           while(z<=K&&(x<=K||y<=K))//合并两个已经排好序的序列
           {
               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++;
           }
       }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&N,&V,&K);
        for(int i=0;i<N;i++)scanf("%d",&weight[i]);
        for(int i=0;i<N;i++)scanf("%d",&value[i]);
        DP();
        printf("%d\n",dp[V][K]);
    }
    return 0;
}

 

posted on 2015-10-22 21:07  恶devil魔  阅读(216)  评论(0编辑  收藏  举报

导航