01背包变种 第k解问题 hdu 2639

先说说普通01包的状态问题吧  

普通的01背包,在状态转移的过程中为了求出最优解,一定是遍历了所有的情况 然后再求的最优解。那么对于第k最优解问题,我们只需要再加一个维度,用来记录每一个状态k优解的状态就好了。

在普通背包过程中 每次的选举的状态为dp[i-1][j],dp[i-1][j-c[i]+w[i]  为了求解最优情况 我们一般是对这两个状态取最大值 然后依次遍历 得到最大值。那么,为了得到第k大的解,我们就需要另外使用数组来对两种状态的所有值记录下来 然后选取第k大的情况

上代码

#include<cstdio>
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
    int val[101],vol[101],dp[1001][33];
    int aa[33],bb[33];
    int n,v,k,t;
    cin>>t;
    while(t--)
    {
        cin>>n>>v>>k;
        for(int i=1;i<=n;i++) cin>>val[i];
        for(int i=1;i<=n;i++) cin>>vol[i];
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            for(int j=v;j>=vol[i];j--)//将 每次优化的k种解记录下来 
            {
                int z;
                for(z=1;z<=k;z++)
                {
                    aa[z]=dp[j][z];
                    bb[z]=dp[j-vol[i]][z]+val[i];
                }
                aa[z]=bb[z]=-1;
                int p,pp,ppp;
                p=pp=ppp=1;
                while(p<=k+1&&(aa[pp]!=-1||bb[ppp]!=-1))//加一个去重的过程 
                {
                    if(aa[pp]>bb[ppp])     dp[j][p]=aa[pp++];    
                    else dp[j][p]=bb[ppp++];
                    if(dp[j][p]!=dp[j][p-1]) p++;
                }
            }
        }
        cout<<dp[v][k]<<endl;
    }
    return 0;
    
}

第k解的问题 让我对背包问题的最优化过程有了一个了解
posted @ 2016-08-10 19:00  猪突猛进!!!  阅读(151)  评论(0编辑  收藏  举报