题目链接:http://poj.org/problem?id=2063
题目大意:直到收到公证人的信,约翰才知道他有一个叔祖父。他得知他已故的伯祖父在南美洲某处收集了一大笔钱,而约翰是唯一的继承人。
约翰暂时不需要那么多钱。但他意识到,将这笔资金存放在一个安全的地方,并让它增长,直到他决定退休,这将是一个好主意。银行使他相信某种债券对他来说是有趣的。
这种债券有固定的价值,每年支付固定数额的利息,在每年年底支付给所有者。这种债券没有固定期限。债券有不同大小可供选择。大的通常利息比较高。不久,约翰意识到,购买债券的最佳组合不是那么简单。而且,几年之后,他的资本就会增长,而日程安排也不得不重新评估。
假设有以下债券:
价值的年度
感兴趣
4000
3000 400
250
资本为1万埃的人可以买两张4 000美元的债券,年息为800美元。购买两支3000美元的债券和一支4000美元的债券是一个更好的主意,因为它每年的利息是900美元。两年后,资本增长到11800美元,出售3000美元的资产并购买4000美元的资产是有道理的,因此年利息增长到1050美元。这就是这个故事不太可能发生的地方:该银行不收取买卖债券的费用。明年的总数是12850美元,也就是4000美元的三倍,每年的利息是1200美元。
这里是你的问题:给定一开始的金额,几年的时间,一组债券的价值和利息,找出在给定的时期内,使用最佳的购买和出售债券的时间表,金额可能增长多少。
输入
第一行包含一个正整数N, N是测试用例的数量。接下来是测试用例。
测试用例的第一行包含两个正整数:开始时的金额(最多100万美元),以及资本可能增长的年数(最多40年)。
下面的行包含一个数字:可用债券的数字d (1 <= d <= 10)。
接下来的d行每一行都包含一个键的描述。债券的描述包括两个正整数:债券的价值和债券的年利率。债券的价值总是1000美元的倍数。债券的利息永远不会超过其价值的10%。
输出
对于每个测试用例,在一个最佳的买入和卖出时间表之后,在一个单独的行上输出期末资本。
样例输入
1
10000年4
2
4000 400
3000 250
样例输出
14050
代码如下:
//1板子题
//2注意年份 以及最后对于money的处理
//3是个完全背包
//Code:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 101010;
int dp[N];
int v[N],w[N];
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int money,year,spci;
scanf("%d%d%d",&money,&year,&spci);
for(int i = 1;i <= spci;i ++) scanf("%d%d",&w[i],&v[i]);
while(year --)//注意年份
{
memset(dp,0,sizeof(dp));
for(int i = 1;i <= spci;i ++)
for(int j = w[i]/1000;j <= money/1000;j ++)
dp[j] = max(dp[j],dp[j - w[i]/1000] + v[i]);
money += dp[money/1000];
}
printf("%d\n",money);
}
}
在这里插入代码片
来源:CSDN
作者:Qota
链接:https://blog.csdn.net/QotaZ/article/details/103959426