poj 2063 Investment

题目描述:

[Description]
John得到了一笔巨款,他决定购买债券来进行增值。这种债券每年年底会支付给John固定的年
利息,没有固定的期限。债券有大有小,大的通常会有更高的收益,所以John希望找到一个最
有的购买方案。此外,每年他的资金都会增长,所有有必要重新计划购买方案。假设有如下两
种债券:
10000元的本金能够购买2个4000元年的债券,比购买2个3000的好,因为利息高,2年后,拥有
11600元,购买2个4000的,1个3000的,1年后变为12650,然后又可以购买3个4000的,以此类
推获得最多的利润。
现在给出本金,年限,和若干债券,你的任务是找到一个最优的购买方案。
[Intput]
第一行一个数T,表示有T组测试数据,每组数据第一行两个数N,Y( 1<=N<=1,000,000 ,
1<=Y<=40
),表示本金和年限,接下来一行一个数d,表示有d种债券,接下来d行,每行两个数xi,yi,表
示第i种债券的价值和年利息。xi为1000的倍数,yi不超过xi的10%。
[Output]
对于每组数据输出一行,表示最优方案的最终的钱数。
[Sample Input]
1
10000 4
2
4000 400
3000 250
[Sample Onput]
14050


思路:

本题就是一个背包 ,但是看 1<=N<=1000000,如果不压缩体积就会超时。由于xi都为1000的整数倍,我们可以
把体积除以1000在动归。
转移方程为f[x]=max(f[x],f[x-w[i]]+v[i]); 


代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,y,d;
int w[20],v[20];
int f[50000+10];


int main()
{
int t;
scanf("%d",&t);
for(int u=1;u<=t;u++)
{
scanf("%d%d",&n,&y);
scanf("%d",&d);
for(int i=1;i<=d;i++)
{
scanf("%d%d",&w[i],&v[i]);
w[i]/=1000;
}


for(int i=1;i<=y;i++)
{
memset(f,0,sizeof(f));
int cmp=n/1000;
for(int j=1;j<=d;j++)
{
for(int k=1;k<=cmp;k++)
{
if(k>=w[j])f[k]=max(f[k],f[k-w[j]]+v[j]);
}
}
n=n+f[cmp];
}
printf("%d\n",n);
}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值