题目:
题意:
一共有
n
n
n个地点,我们需要依次经过
一开始有一个耐久为
w
w
w的稿子
有两种地点,资源点和维护点
分析:
正着做非常头疼,因为会发现某个点的答案不是最优,但可能是最优方案中的一步
说白了,貌似存在有后效性
老谚语,正难则反,设
f
i
f_i
fi表示
i
∼
n
i\sim n
i∼n的最优解
这样设是因为我们原本的难处在于某个时刻的
p
p
p怎么求出来
可不妨将一开始的
w
w
w视为
1
1
1,最后答案
∗
w
*w
∗w也是一样的
相应的,我们将在第
i
i
i点时的
p
p
p也视为
1
1
1,倒着推转移方程式,会有:
f
i
=
m
a
x
{
f
i
+
1
,
f
i
+
1
∗
(
1
−
k
%
)
+
x
}
f_i=max\{f_{i+1},f_{i+1}*(1-k\%)+x\}
fi=max{fi+1,fi+1∗(1−k%)+x}
对于维护点也差不多
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
inline LL read()
{
LL s=0,f=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {s=s*10+c-'0';c=getchar();}
return s*f;
}
double f[100005];
int t[100005],v[100005];
int main()
{
freopen("exploit.in","r",stdin);
freopen("exploit.out","w",stdout);
int n=read(),k=read(),c=read();double w=read();
for(int i=1;i<=n;i++) t[i]=read(),v[i]=read();
for(int i=n;i>=0;i--)
{
if(t[i]==1) f[i]=max(f[i+1],f[i+1]*(1-0.01*k)+v[i]);
else f[i]=max(f[i+1],f[i+1]*(1+0.01*c)-v[i]);
}
printf("%.2lf",f[1]*w);
return 0;
}