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

    P1858 多人背包

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


    调试日志: 初始化没有赋给 dp[0]


    Solution

    首先补充个知识点啊, 要求装满的背包需要初始赋 (-inf), 边界为 (dp[0] = 0)
    (k) 优解的01背包
    (dp[j][k]) 表示 容量为 (j) 的背包的第 (k) 优解
    用到了归并排序的思想
    对于第 (i) 个物品, 容量为 (j), 我们有两种选择:

    1. 选第 (i) 个物品
    2. 不选第 (i) 个物品

    对于 (1-k) 中的每一个解做抉择, 我们可以得到 (2k) 种答案
    由于答案分两边(选或不选)内部有序, 归并得到前 (k) 优即可
    复杂度 (O(nmk))

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #define LL long long
    #define REP(i, x, y) for(int i = (x);i <= (y);i++)
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const int maxn = 10019;
    int K, V, num;
    int w[maxn], v[maxn];
    int temp[maxn];
    int dp[maxn][119];
    int main(){
    	K = RD(), V = RD(), num = RD();
    	REP(i, 1, num)w[i] = RD(), v[i] = RD();
    	REP(i, 0, V)REP(k, 1, K)dp[i][k] = -1e9;
    	dp[0][1] = 0;
    	REP(i, 1, num){
    		for(int j = V;j >= w[i];j--){
    			int p1 = 1, p2 = 1, cnt = 0;
    			while(cnt <= K){
    				if(dp[j][p1] > dp[j - w[i]][p2] + v[i])temp[++cnt] = dp[j][p1++];
    				else temp[++cnt] = dp[j - w[i]][p2++] + v[i];
    				}
    			REP(k, 1, K)dp[j][k] = temp[k];
    			}
    		}
    	int ans = 0;
    	REP(i, 1, K)ans += dp[V][i];
    	printf("%d
    ", ans);
    	return 0;
    	}
    
  • 相关阅读:
    print 带颜色打印
    bootstrap-duallistbox使用
    Linux 查看和更改系统字符集
    nginx 不重装实现动态添加模块
    ubuntu 安装openssh-server出现依赖关系解决
    linux安装和使用zookeeper
    网页背景蜘蛛丝特效
    RabbitMQ与SpringBoot整合
    Redis常用命令
    设计模式(Design Patterns)
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9858413.html
Copyright © 2011-2022 走看看