zoukankan      html  css  js  c++  java
  • 洛谷P1858多人背包(k优解背包)

    题目描述

    求01背包前k优解的价值和

    输入输出格式

    输入格式:

    第一行三个数K、V、N

    接下来每行两个数,表示体积和价值

    输出格式:

    前k优解的价值和

    输入输出样例

    输入样例#1:

     2 10 5
     3 12
     7 20
     2 4
     5 6
     1 1
    

    输出样例#1:

     57
    

    说明

    对于100%的数据,K≤50,V≤5000,N≤200


    (Solution:)

    求第k优解的背包问题当然还是用背包做啦!

    由于要求前k优解,所以我们可以开一个 (f_{j,k}) 来表示容量为 (j) 的第 (k) 优解,递推的时候由于你记录的是 (k) 优解,那么最多产生 (2*k) 种情况,我们不妨可以再开一个 (now) 数组来记录这 (2*k) 种情况,然后使它有序并把前 (k) 个赋值给 (f_{j,k}​) ,最后统计一下答案就好了qwq​

    上代码,代码中会有具体解释:

    #include<bits/stdc++.h>
    #define il inline
    using namespace std;
    il int read(){
        int f=1,w=0;char c=0;
        while(!isdigit(c))
        {
            if(c=='-') f=-1;
            c=getchar();
        }
        while(isdigit(c)) w=w*10+(c^48),c=getchar();
        return f*w;
    }//快读不解释
    int k,v,n,w[210],c[210],f[5010][55],now[5010],ans;
    int main(){
        k=read(),v=read(),n=read();
        for(int i=1;i<=n;i++) c[i]=read(),w[i]=read();
        memset(f,-0x3f,sizeof(f));
        f[0][1]=0;//初始化
        for(int i=1;i<=n;i++)
            for(int j=v;j>=c[i];j--)
            {
                int c1=1,c2=1,m=0;
                while(m<=k)
                {
                    if(f[j][c1]>f[j-c[i]][c2]+w[i])
                        now[++m]=f[j][c1++];
                    else now[++m]=f[j-c[i]][c2++]+w[i];
                }//在赋值过程中一并排完序,f[j]与f[j-c[i]]都是有序的
                for(int o=1;o<=k;o++) f[j][o]=now[o];
            }
        for(int i=1;i<=k;i++) ans+=f[v][i];//计算答案
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    抱歉
    The area
    sort
    Problem D
    Problem B
    错排
    第8集 仪表开关电源照明原理图
    第7集 驱动与电气原理图绘制
    第6集 初步使用EPLAN部件库部件功能
    第5集 软件中建立项目结构
  • 原文地址:https://www.cnblogs.com/ajy-shi-cj-zui-cai/p/10385588.html
Copyright © 2011-2022 走看看