一只猫拥有t个单位的时间,在每个单位时间里,它可以选择沉默、叫一声“喵”、或者叫两声“喵喵”
对于每个单位时间,均有一个实数v[i],猫咪叫一声可获得v[i]的进化量,叫两声可以获得(v[i])^2的进化量
然而它在某个单位时间如果叫了两声,下一单位时间必须保持沉默来休息。
求最大进化量
一道很简单的DP
设 : : :
f [ i ] [ 0 ] f[i][0] f[i][0] 表示到第i个单位时间选择沉默时的最大进化量
f [ i ] [ 1 ] f[i][1] f[i][1] 表示到第i个单位时间选择猫叫一下的最大进化量
f [ i ] [ 2 ] f[i][2] f[i][2] 表示到第i个单位时间选择猫叫两下的最大进化量
状态转移方程则为 : : :
f [ i ] [ 0 ] = m a x ( f [ i − 1 ] [ 0 ] , f [ i − 1 ] [ 1 ] , f [ i − 1 ] [ 2 ] ) f[i][0]=max(f[i-1][0],f[i-1][1],f[i-1][2]) f[i][0]=max(f[i−1][0],f[i−1][1],f[i−1][2])
f [ i ] [ 1 ] = m a x ( f [ i − 1 ] [ 0 ] , f [ i − 1 ] [ 1 ] ) + v [ i ] f[i][1]=max(f[i-1][0],f[i-1][1])+v[i] f[i][1]=max(f[i−1][0],f[i−1][1])+v[i]
f [ i ] [ 2 ] = m a x ( f [ i − 1 ] [ 0 ] , f [ i − 1 ] [ 1 ] ) + ( v [ i ] ∗ v [ i ] ) f[i][2]=max(f[i-1][0],f[i-1][1])+(v[i]*v[i]) f[i][2]=max(f[i−1][0],f[i−1][1])+(v[i]∗v[i])
输出时保留4位小数即可
#include
using namespace std;
int n;
double v[800005],f[800005][3];
double Max(double a,double b)
{
return a>b?a:b;
}
double read()
{
double x=0,op=1;
char ch=getchar();
while (ch<'0'||ch>'9')
{
if(ch=='-') op=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9')
x=x*10+(double)(ch-48),ch=getchar();
if(ch!='.') return x*op;
double cnt=10;
ch=getchar();
while(ch>='0'&&ch<='9')
x=x+((double)(ch-48)/cnt),ch=getchar(),cnt*=10.0;
return x*op;
}//快读
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
v[i]=read();
for(int i=1;i<=n;i++)
{
f[i][0]=Max(f[i-1][0],Max(f[i-1][1],f[i-1][2]));
f[i][1]=Max(f[i-1][0],f[i-1][1])+v[i];
f[i][2]=Max(f[i-1][0],f[i-1][1])+(v[i]*v[i]);
}
cout<