zoukankan      html  css  js  c++  java
  • Luogu P1858 多人背包

    gate

    求01背包前k优解的价值和(题面还挺亲切的)

    本来我想的是直接边跑01背包边记录,最后排序...

    然后意识到,这种方法是枚举不全的。

    看了眼题解...要多开一维!

    k的范围很小,f[i][j]表示空间为i,是第j优解。

    那么,因为有许多j,所以对于每个不一样的j,

    f[i][j]既可能从f[i-c][...]+w转移过来,也可能从f[i][...]转移过来。

    用类似于归并排序的方法:

    维护两个指针t1,t2;

    同时为了防止新的f覆盖原来的影响后续的状态转移,用一个临时的g[]记录,最后再转移过去。

    那么就有g[t] = max(f[j-c][t1++]+w,f[j][t2++])

    最后答案统计f[m][1-k]就可以了。

    代码如下

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #define MogeKo qwq
    #define Darcy amour
    using namespace std;
    
    const int maxn = 1e5+10;
    const int INF = 0x3f3f3f3f;
    int k,m,n,c,w,ans,f[maxn][60],g[60];
    
    int main() {
        scanf("%d%d%d",&k,&m,&n);
        memset(f,-INF,sizeof(f));
        f[0][1] = 0;
        for(int i = 1; i <= n; i++) {
            scanf("%d%d",&c,&w);
            for(int j = m; j >= c; j--) {
                int t1 = 1,t2 = 1;
                for(int t = 1; t <= k; t++) {
                    if(f[j-c][t1] + w > f[j][t2])
                        g[t] = f[j-c][t1++] + w;
                    else
                        g[t] = f[j][t2++];
                }
                for(int t = 1; t <= k; t++)
                    f[j][t] = g[t];
    
            }
        }
        for(int i = 1; i <= k; i++)
            ans += f[m][i];
        printf("%d",ans);
        return 0;
    }
    View Code

     

  • 相关阅读:
    java代码,继承。。。主要是传值,赋值。
    java代码继承。。。找出不能继承父类方法的问题
    java代码继承super
    HDU 6114 Chess
    #113. 【UER #2】手机的生产
    uoj 118 赴京赶考
    戏game
    序sort
    迷enc
    Jupyter 同时支持python2、python3 kernel
  • 原文地址:https://www.cnblogs.com/mogeko/p/11715703.html
Copyright © 2011-2022 走看看