题解部分:
从题面上来看,这是个dp(递推)的题目。
但是dp要满足无后效性,但这个题为了取最值,得考虑从当前开始一直持续到结束的p的影响。
这让我们怎么满足无后效性??
(当时我一懵)
but,
如果反过来,那么他不就满足无后效性了吗QWQ。
也就是无前效性。
具体来说,如果p对以后的造成影响,那么我们从最后一位开始dp,往前推,那么p只会对已经推完的造成影响,不会对没推的造成影响,这样不就满足无后效性了吗?
那么只要把题目中讲到的运算反着来写(+变成-),就ok了。
我们用dp[i]来表示从最后一个n到i的最优解,那么dp转移方程就是:
if(type[i]==1)
dp[i]=max(dp[i+1],rqych[i]+dp[i+1]*(1-0.01*k));
else
dp[i]=max(dp[i+1],dp[i+1]*(1+0.01*c)-rqych[i]);
对于每一种type分别进行判断。
AC代码:
#include<cstdio> #include<iostream> using namespace std; int read()//自研快读 { int ans=0; char ch=getchar(),last=' '; while(ch<'0'||ch>'9')last=ch,ch=getchar(); while(ch>='0'&&ch<='9')ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar(); return last=='-'?-ans:ans; } int n,k,c,w,x,type[100001]; double dp[100001],rqych[100001];//rqy和ych是两个神仙 int main(){ n=read(),k=read(),c=read(),w=read(); for(int i=1;i<=n;i++) { type[i]=read();rqych[i]=read(); } for(int i=n;i>=1;i--)//倒着找 { if(type[i]==1)//主要dp方程 dp[i]=max(dp[i+1],rqych[i]+dp[i+1]*(1-0.01*k)); else dp[i]=max(dp[i+1],dp[i+1]*(1+0.01*c)-rqych[i]); } printf("%0.2lf",dp[1]*w); }
没了。。
QWQ