您的位置:首页 > 其它

POJ 2063 Investment 滚动数组+完全背包

2016-05-05 19:45 351 查看

题目链接:

http://poj.org/problem?id=2063

题意:

你现在有现金m元,你要做n年的存款投资,给你k种投资方式,每种需要现金vi元,能获得xi元的理论,一年到期后你要利用拿到的本息和重新投资,问这样做n年最后能拿到的最大本息和是多少。

题解:

dp[i]表示你花i元去投资能获得的最大利润。

则第一年你要做的就是dp[1]->dp[m](m为初始金额) 假设获得的最大奖金为m_inte[i];

则第二年要做的是dp[m+1]->dp[m+m_inte[i]]

...

这样,完全背包一直做n年就可以了。

由于dp数组最多只能开到7*10^6(30000kb),所以这里用滚动数组的方式来节约空间,否则会爆空间限制。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn = 1e6+10;
const int mod = maxn;

int n;
int mny, ye;
int valu[11], inte[11];
int dp[maxn];

void init() {
memset(dp, -1, sizeof(dp));
}

int main() {
int tc;
scanf("%d", &tc);
while (tc--) {
init();
scanf("%d%d", &mny, &ye);
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d%d", valu + i, inte + i);
int idx = 1000; dp[0] = 0;
int ans = 0;
while (ye--) {
for (; idx <= mny; idx += 1000) {
dp[idx%mod] = -1;
for (int i = 0; i < n; i++) {
if (idx - valu[i] < 0) continue;
if (dp[(idx - valu[i])%mod]!=-1) {
dp[idx%mod] = max(dp[idx%mod], dp[(idx - valu[i])%mod] + inte[i]);
ans = max(ans, dp[idx%mod]);
}
}
}
mny += ans;
}
printf("%d\n", mny);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: