POJ 2063 Investment 完全背包
fakeDescription: 吃土魔法少女经济不景气辣! 变出借来了为1000的倍数的钱打算去投资股票辣! (顺便吃土少女说她最多只能借来1000000元)告诉你吃土少女将会吃土投资几年以及每种股票的年收益和每一股的价格 现在吃土少女任命你为投资顾问制定每年的投资方案最大化收益。吃土少女不关心你怎么买的。只需要你写个程序告诉她她最后持有多少财富。吃土少女等着你来拯救!
以上题目描述都是我口胡的。233.不过意思对了就行了233
由于每年有一次可以选择买卖股票的机会, 我们可以看做每年dp一下当年的最优计划。
然后我们可以用f[i][j]表示枚举到第i种股票时你手里还有j的可用资金时的最大财富
于是转换方程就出来辣:
f[i][j] = max(f[i - 1][j], f[i - 1][j - cost[i]] + val[i]);
其中cost是每一股的价格 val是年收益。
然后看到都是1000的倍数啦,除以1000优化一下空间和时间辣
所以核心伪代码:
for y = 1 to total year{ tmp资金 = 去年结余 / 1000; for i = 1 to n for j = cost[i] to tmp资金 //方程!QAQ 总财富 += f[tmp资金]; }
然后输出总财富就好啦
注意一定要滚动数组优化一下不然容易MLE
1 #include <iostream> 2 #include <string.h> 3 #include <math.h> 4 #include <stdlib.h> 5 #include <stdio.h> 6 #include <algorithm> 7 #define ll long long 8 using namespace std; 9 const int MAXN = 100010; 10 int f[MAXN], cost[15], val[15], cs; 11 int n, init, year, mon; 12 int main() 13 { 14 scanf("%d", &cs); 15 while(cs --){ 16 scanf("%d%d%d", &init, &year, &n); 17 mon = init; init /= 1000; 18 for(int i = 1; i <= n; i ++) { 19 scanf("%d%d", &cost[i], &val[i]); 20 cost[i] /= 1000; 21 } 22 for(int y = 1; y <= year; y ++){ 23 int tmp = mon / 1000; 24 memset(f, 0, sizeof(f)); 25 for(int i = 1; i <= n; i ++){ 26 for(int j = cost[i]; j <= tmp; j ++){ 27 f[j] = max(f[j - cost[i]] + val[i], f[j]); 28 } 29 } 30 mon += f[tmp]; 31 } 32 printf("%d\n", mon); 33 } 34 return 0; 35 }
NAILED IT !
-------------------------------
吃土少女对您表示由衷的感谢!
时间: 2024-10-17 10:35:14