hdu2639 Bone Collector II 01背包第K优解

#include <stdio.h>
#include <math.h>
#include <string.h>
using namespace std;
int f[1001][33];//f[i][j]表示i体积下第j优解
int c[1001],w[1001];
int max(int a,int b)
{
    return a>b?a:b;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m,i,j,k,p,a[33],b[33];
        scanf("%d%d%d",&n,&m,&k);
        for(i=0;i<n;i++)
            scanf("%d",&w[i]);
        for(i=0;i<n;i++)
            scanf("%d",&c[i]);
        memset(f,0,sizeof(f));
        for(i=0;i<n;i++)
        {
            for(j=m;j>=c[i];j--)
            {
                for(p=1;p<=k;p++)
                {
                    a[p]=f[j-c[i]][p]+w[i]; //在f[i]=max(f[j],f[j-c[i]]+w[i])中产生后续优解,小的为次优   
                    b[p]=f[j][p];
                }
                a[p]=b[p]=-1;
                int x,y,z;
                x=y=z=1;
                while(z<=k&&(a[x]!=-1||b[y]!=-1))//产生分歧后找到其中最大的k的保留
                {
                    if(a[x]>b[y])
                    {
                        f[j][z]=a[x];
                        x++;
                    }
                    else
                    {
                        f[j][z]=b[y];
                        y++;
                    }
                    if(f[j][z]!=f[j][z-1])//去掉重复了的优解
                        z++;
                }
            }
        }
        printf("%d\n",f[m][k]);
    }
    return 0;
}

你可能感兴趣的:(01背包)