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

    题面

    01背包的前(k)优解

    思路

    我们先考虑一下最平凡的01背包问题是如何进行求解的,一维状态下

    (f[j]=max(f[j],f[j-w[i]]+v[i]))

    有第k优解的限制怎么办,不妨加一个维度,把动态规划的转移想象成图中点与点之间

    的移动

    (f[j][k])表示装满体积为(j)的背包的第(k)优解

    我们发现,最优解的数值是随着(k)增大而减小的,满足单调性

    很容易发现,我们需要记录用其他物品来填充背包是否能得到更优解.

    因此我们需要记录一个变量c1表示体积为j的时候的第c1优解能否被更新.

    再去记录一个变量c2表示体积为j-v[i]的时候的第c2优解.

    这样也就回到了01背包的最基本的情况,选还是不选

    显然对于体积为(j)的情况,它的前(k)优解可以由以上两种情况转移过来

    那么我们可以在转移的时候记录一个中间数组,(now[])

    所以有以下的代码

    int cnt = 0;//对于每个j,我们都需要清空一下now数组
    int c1 = 1;//情况1的最优解
    int c2 = 1;//情况2的最优解
          while (cnt <= K) {//求出前k优解
            if (dp[j][c1] > dp[j - w[i]][c2] + v[i])
              now[++cnt] = dp[j][c1++];//如果情况1的价值大,取出情况1的价值
            else {
              now[++cnt] = dp[j - w[i]][c2++] + v[i];//如果情况2的价值大,取出情况2的价值
            }
          }
          for (int z = 1; z <= K; z++) {
            dp[j][z] = now[z];//进行更新
    

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 5001;
    int dp[5001][51];
    int v[N], w[N];
    int now[N];
    int K, n, m;
    long long ans;
    int main() {
      scanf("%d%d%d", &K, &m, &n);
      memset(dp, -0x3f, sizeof(dp));
      dp[0][1] = 0;
      for (int i = 1; i <= n; i++) {
        scanf("%d%d", &w[i], &v[i]);
      }
      for (int i = 1; i <= n; i++) {
        for (int j = m; j >= w[i]; j--) {
          int cnt = 0;
          int c1 = 1;
          int c2 = 1;
          while (cnt <= K) {
            if (dp[j][c1] > dp[j - w[i]][c2] + v[i])
              now[++cnt] = dp[j][c1++];
            else {
              now[++cnt] = dp[j - w[i]][c2++] + v[i];
            }
          }
          for (int z = 1; z <= K; z++) {
            dp[j][z] = now[z];
          }
        }
      }
      for (int i = 1; i <= K; i++) ans += dp[m][i];
      printf("%lld
    ", ans);
      return 0;
    }
    
  • 相关阅读:
    vue中处理ie兼容性问题
    vue使用websocket
    vue-cli中使用sass的坑
    really_probe()
    ro.boot.bootreason property设置(androidboot.xxxx bootargs)
    kernel exception vector table
    compile/link misc
    user space syscall/library API misc
    LIUNX SHELL中-a 到-z的解释
    getenforce/setenforce
  • 原文地址:https://www.cnblogs.com/bangdexuanyuan/p/14071776.html
Copyright © 2011-2022 走看看