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;
    }
    				
    
  • 相关阅读:
    关于JS中涉及的常用类型转换及运算符表达式
    关于JS脚本语言的基础语法
    钱、车、房、能力
    三数中找最大值
    C#语句
    进制转换
    自动拆装箱、可变参数
    使用dom4j解析xml
    jaxp的dom方式操作(查找、添加、修改、删除、遍历节点)
    xml-dtd
  • 原文地址:https://www.cnblogs.com/akoasm/p/15153885.html
Copyright © 2011-2022 走看看