POJ 2063 Investment (完全背包)

题目类型  完全背包

题目意思
你刚开始拥有金钱 x (x <= 1000 000) 现在有 n (1 <= n <= 10) 种债券可以投资
每种债券的售价均是1000的整数倍且年收益不超过售价的 10% 现在 n 种债券的售价和年收益已给出 问 y 年后你最多拥有多少钱 ( y <= 40)
债券的购买数量不设上限 例如你拥有 2000 元 有一种债券售价 1000 元 年收益是 100 元 那么你可以买 2 份这种债券 一年后你拥有的钱是 
2000(两份债券的价值) + 100 * 2(每份债券收益100元) = 2200 每一年收益计算后你可以重新调整你拥有的债券的情况 即把收益较少的债券卖出去用
得到的钱和收益的钱买收益更好的债券 参照题目中的例子即可理解清楚

解题方法
很明显的完全背包 
由于债券的售价都是 1000 的整数倍 那么我们可以把债券的售价除以 1000 然后用 dp[i] 表示 i*1000元在最优的策略下 一年的最大收益 
那么可以用完全背包的方法计算出一定范围内的金钱在一年内最大的收益 (债券的售价相当于物品的体积 收益相当于物品的价值)
预处理出这个收益数组后模拟一次投资过程即可 (详细见代码)
通过计算可以发现 所能拥有的金钱数最大是 (40000+) × 1000 即dp数组需要开50000左右

参考代码 - 有疑问的地方在下方留言 看到会尽快回复的
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int dp[50000];

int main() {
	//freopen("in", "r", stdin);
	int t;
	scanf("%d", &t);
	while(t--) {
		int c, y, n;
		scanf("%d%d", &c, &y);
		scanf("%d", &n);
		memset(dp, 0, sizeof(dp));
		for( int i=0; i<n; i++ ) {
			int a, b;
			scanf("%d%d", &a, &b);
			a /= 1000;
			for( int j=a; j<50000; j++ ) { // 用完全背包 计算出一定金钱下能获得的最大收益
				if(dp[j] < dp[j-a] + b) dp[j] = dp[j-a] + b;
			}
		}
		while(y--) {
			c += dp[c/1000]; // 每次本金 + 收益作为新的本金
		}
		printf("%d\n", c);
	}
	return 0;
}



你可能感兴趣的:(动态规划)