zoukankan      html  css  js  c++  java
  • 金明的预算方案

    题目描述

    有一些物品,分为主件和附件,买附件必须先买逐渐,问在固定的钱数下,能获得的最大价值是多少。

    范围

    \(N \leq 32000,m < 60,v \leq 10000\)

    题解

    有依赖的背包问题。

    假设一个主件\(p\)和两个附件\(a,b\),那么他们的购买方案有:

    1. \(p\)
    2. \(p,a\)
    3. \(p,b\)
    4. \(p,a,b\)

    这四种只能选择一种来进行购买,对于每个形如此类,拆分成若干个购买方案,分组背包即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 32010;
    const int M = 60;
    typedef pair<int,int> PII;
    vector <PII> qr[M];
    #define pb(x) push_back(x)
    PII own[M];
    int n,m;
    #define mk(x,y) make_pair(x,y)
    int f[N];
    int main () {
    	cin >> n >> m;
    	for(int i = 1;i <= m; ++i) {
    		int v,p,q;
    		cin >> v >> p >> q;p *= v;
    		if(q == 0) own[i] = mk(v,p);
    		else {
    			qr[q].pb(mk(v,p));
    		}
    	}
    	for(int i = 1;i <= m; ++i) {
    		for(int j = n;j >= 0; --j) {
    			for(int k = 0;k < (1 << qr[i].size()); ++k) {
    				int l = own[i].first;
    				int r = own[i].second;
    				//cout << l << ' '<< r << endl;
    				for(int p = 0;p < (qr[i].size()); ++p) {
    					if(k >> p & 1) {
    						l += qr[i][p].first;
    						r += qr[i][p].second;
    					}
    				}
    				if(j >= l) f[j] = max(f[j],f[j - l] + r);
    			}
    		}
    	}
    	//for(int i = 0;i <= m; ++i) cout << f[i] << ' ';
    	cout << f[n] << endl;
    	return 0;
    }
    				
    
  • 相关阅读:
    Powershell增加ADB命令
    电脑通过ADB截图脚本
    常用Website List
    护眼豆绿色背景RGB
    xshell方便设置
    解决 Xshell6|Xftp6 强制升级
    beyond compare 4.2.9桌面右键集成的问题修复
    Ubuntu中Samba的安装配置和使用
    excel设置保护工作区域
    【转载】学习 Qt 编程的好书推荐
  • 原文地址:https://www.cnblogs.com/akoasm/p/15153885.html
Copyright © 2011-2022 走看看