01背包第k大

来源:互联网 发布:淘宝里面的关键词检索 编辑:程序博客网 时间:2024/04/30 14:13

嗯……这道题其实还是挺简单的……
然后我就不会做了QAQ
实际上就是设
f[i][j][k]为第i个物品,容量为j,第k个背包的价值。
那么则有f[i][j][p] =
f[i - 1][j - w[i]][1…K] + val[i]与f[i - 1][j][1…K]的第p个
然后因为我懒了一下……
我想:
诶?询问最大值?
前k大?
然后搞了个堆下来……
然后就TLE了TAT
(话说我好像用堆就从来没有用对过……

#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <iostream>#define Rep(i,n) for(int i = 1;i <= n;i ++)#include <queue>#define CLR(a,b) memset(a,b,sizeof(a))using namespace std;int K,n,m,f[5005][55],val[205],w[205];void Merge(int now,int hv){    int tmp[105];    int a = 1,b = 1,cnt = 0;    while(a <= K && b <= K)    {        if(f[hv][a] > f[hv - w[now]][b] + val[now])            tmp[++ cnt] = f[hv][a ++];        else tmp[++ cnt] = f[hv - w[now]][b ++] + val[now];    }    Rep(i,K)f[hv][i] = tmp[i];}int main (){    scanf("%d%d%d",&K,&m,&n);    Rep(i,n)        scanf("%d%d",&w[i],&val[i]);    CLR(f,-127);    f[0][1] = 0;    Rep(i,n)    {        for(int j = m;j >= w[i];j --)            Merge(i,j);    }    int ans = 0;    Rep(i,K)ans += f[m][i];    printf("%d\n",ans);    return 0;}
0 0
原创粉丝点击