• 多人背包


           题目在这里qwq

    题目描述:求01背包前k优解的价值和

    输入格式:第一行三个数k,v,n 接下来n行每行两个数 体积和价值

    输出格式:前k优解的价值和

        

    正解:

      在01背包的基础上再加上一个维度

      f[m][k]:重量为m的第k优解  注意要初始化为-inf 而不是0 因为背包要填满

      用tmp[k] 来存当前求的体积为m时的第k优解 最后用它来更新f[m][k]即可

      <下面的栗子中用到的数组(也是代码里的数组)>:

        a[i] 第i件物品的体积;b[i] 第i件物品的价值  

        然后以下的转移的外层循环就是一般01背包的循环 具体见代码

            假设我们现在要求f[m][k] (k=1,2,…,5)

      f[m][1]显然只能为max(f[m][1],f[m-a[i]][1]+b[i])

      若f[m][1]=f[m-a[i]]+b[i] 那么f[m][2]=max(f[m][1],f[m-a[i]][2]+b[i])

            若f[m][1]=f[m][1] 那么f[m][2]=max(f[m][2],f[m-a[i]][1]+b[i])

      以此类推 其实应该还是比较好理解的 但是感觉写好code有一点点难

       

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define go(i,a,b) for(register int i=a;i<=b;i++)
    #define goo(i,a,b) for(register int i=a;i>=b;i--)
    #define inf 210000000
    using namespace std;
    int read()
    {
      int x=0,y=1;char c=getchar();
      while(c<'0'||c>'9') c=getchar();
      while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
      return x*y;
    }
    int k,v,n,t,t1,t2,ans,a[210],b[210],f[5010][60],tmp[60];
    int main()
    {
        k=read();v=read();n=read();
        go(i,1,n) a[i]=read(),b[i]=read();
        go(i,0,v) go(j,1,k) f[i][j]=-inf;
        f[0][1]=0;
        go(i,1,n)
           goo(j,v,a[i]) {
             t1=1;t2=1;t=0; //t1,t2 相当于两个指针吧 具体理解见上面分析中的栗子
             while(t<=k) {
               if(f[j][t1]<f[j-a[i]][t2]+b[i]) tmp[++t]=f[j-a[i]][t2++]+b[i];
               else tmp[++t]=f[j][t1++];
             }
             go(x,1,k) f[j][x]=tmp[x];
        }
        go(i,1,k) ans+=f[v][i];
        printf("%d",ans);
        return 0;
    }
    View Code

     

     

    光伴随的阴影
  • 相关阅读:
    并发编程-process对象的其他属性方法
    Python json格式处理
    msf制作反弹shell
    Windows渗透备忘录
    WPF listbox实现多列显示数据
    Postgresql插入或更新操作upsert
    Windows 10 IoT Core Samples
    物联网平台开源
    实现领域驱动设计
    wpf Visibility 动画
  • 原文地址:https://www.cnblogs.com/forward777/p/10314718.html
Copyright © 2020-2023  润新知