题目描述
在以后的若干天里戴维将学习美元与德国马克的汇率。编写程序帮助戴维何时应买或卖马克或美元,使他从100美元开始,最后能获得最高可能的价值。
输入输出格式
输入格式
输入文件的第一行是一个自然数N,1≤N≤100,表示戴维学习汇率的天数。
接下来的N行中每行是一个自然数A,1≤A≤1000。第i+1行的A表示预先知道的第i+1天的平均汇率,在这一天中,戴维既能用100美元买A马克也能用A马克购买100美元。
输出格式
输出文件的第一行也是唯一的一行应输出要求的钱数(单位为美元,保留两位小数)。
注意:考虑到实数算术运算中进位的误差,结果在正确结果0.05美元范围内的被认为是正确的,戴维必须在最后一天结束之前将他的钱都换成美元。
输入输出样例
输入样例
5
400
300
500
300
250
输出样例
266.66
样例解释
Day 1 … changing 100.0000 美元 = 400.0000 马克
Day 2 … changing 400.0000 马克 = 133.3333 美元
Day 3 … changing 133.3333 美元 = 666.6666 马克
Day 5 … changing 666.6666 马克 = 266.6666 美元
分析
又来水DP了。。。
定义 f [ i ] [ 0 ] f[i][0] f[i][0] 为前 i i i 天将 $100$$ 转化为马克的最大值, f [ i ] [ 1 ] f[i][1] f[i][1] 为前 i i i 天将 $100$$ 转化为美元的最大值。根据定义,我们很容易地得出状态转移方程:
f
[
i
]
[
0
]
=
max
{
f
[
i
−
1
]
[
0
]
,
f
[
i
−
1
]
[
1
]
×
a
[
i
]
}
f
[
i
]
[
1
]
=
max
{
f
[
i
−
1
]
[
1
]
,
f
[
i
−
1
]
[
0
]
÷
a
[
i
]
}
f[i][0]=\max\{ f[i-1][0],f[i-1][1]\times a[i] \}\\ f[i][1]=\max\{ f[i-1][1],f[i-1][0]\div a[i] \}
f[i][0]=max{f[i−1][0],f[i−1][1]×a[i]}f[i][1]=max{f[i−1][1],f[i−1][0]÷a[i]}
其中,
a
[
i
]
a[i]
a[i] 表示在第
i
i
i 天的汇率。
根据方程,我们也不难得出程序。
代码
#include <iostream>
#include <cstdio>
using namespace std;
double f[105][2],a[105];
int n;
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%lf",&a[i]);
f[0][1]=100;
for (int i=1;i<=n;i++) {
f[i][1]=max(f[i-1][0]/a[i],f[i-1][1]);
f[i][0]=max(f[i-1][1]*a[i],f[i-1][0]);
}
printf("%.2lf",f[n][1]);
return 0;
}