【DP】猫咪的进化
貓咪的進化
題目大意:
有n個實數,每一個實數可以選,可以不選,也可以選擇它的平方,但如果選擇了它的平方,就不能選擇下一個數或下一個數的平方,求選出來的數的和最大是多少
原題:
題目描述
對于一只貓咪來說,它是有九條命的。但是并不是所有的貓咪都是這樣,只有那些造化很高的貓咪才能死而復生。而且對于這樣的貓咪,如果它能夠活到第九條命,那么它最終可以變成任何一種它想成為的動物(當然也可以繼續做貓咪啦),我們稱這樣的貓咪為貓神。現在一只獲得了進化機會的貓咪,受到了女神snowharmony的考驗。
它擁有t個單位的時間,在每個單位時間里,它可以選擇沉默、叫一聲“喵”、或者叫兩聲“喵喵”。對于每個單位時間,均有一個實數v[i],貓咪叫一聲可獲得v[i]的進化量,叫兩聲可以獲得(v[i])^2的進化量,然而它在某個單位時間如果叫了兩聲,下一單位時間必須保持沉默來休息。
女神Snowharmony要求它以一定的方式叫,只有它最終獲得了最大的進化量,它才能進化為貓神,從而變為它想成為的動物——人族zsw95。
請你幫助它計算最大進化量,使他進化為為貓神zsw95。
輸入
第一行一個整數t。
第二行,t個實數v[i]。
輸出
最大的進化量,保留四位小數。
輸入樣例
3 9 2 1輸出樣例
82.0000說明
1<=t<=800000,-255.00<=v[i]<=255.00
計算結果不超過maxlongint
解題思路:
用f[i][0],f[i][1],f[i][2]分別表示這個數字不選,選,選平方,就得出了以下狀態轉移方程:
f[i][0]=max{(f[i?1][0]f[i?1][1]f[i?1][2]f[i][1]=max{f[i?1][0]f[i?1][1]}+xf[i][2]=max{f[i?1][0]f[i?1][1]}+x?xf[i][0]=max\left\{(\begin{matrix}f[i-1][0]\\ f[i-1][1]\\ f[i-1][2]\end{matrix}\right.\\f[i][1]=max \begin{Bmatrix}f[i-1][0] \\ f[i-1][1]\end{Bmatrix} +x\\f[i][2]=max \begin{Bmatrix}f[i-1][0] \\ f[i-1][1]\end{Bmatrix} +x*xf[i][0]=max????(f[i?1][0]f[i?1][1]f[i?1][2]?f[i][1]=max{f[i?1][0]f[i?1][1]?}+xf[i][2]=max{f[i?1][0]f[i?1][1]?}+x?x
第一個:三種情況,都可以不選
第二個:上一個不選平方才可以選他
第三個:上一個不選平方才可以選平方
然后因為時間的原因,要加快讀
代碼:
#include<cstdio> #include<iostream> #include<cstring> using namespace std; int n; double x,f[800005][5]; double read()//快讀 {char ch;int wh=1;double z=0,y=1;ch=getchar()while(ch<'0'||ch>'9')//前面的空格{if (ch=='-') y=-1;ch=getchar();}while(ch>='0'&&ch<='9')//數字{z=z*10+(double)(ch-48);ch=getchar();}if(ch!='.') return z*y;//非小數ch=getchar();while(ch>='0'&&ch<='9')//小數部分{wh*=10;z+=(double)(ch-48)/wh;ch=getchar();}return z*y; } int main() {scanf("%d",&n);for (int i=1;i<=n;++i){x=read();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])+x;f[i][2]=max(f[i-1][0],f[i-1][1])+x*x;}printf("%.4lf",max(f[n][0],max(f[n][1],f[n][2])));//要最優的 }總結
- 上一篇: 开始搜集赚钱的案例赚钱小案例
- 下一篇: 老用户眼中的苹果2021款iMac,优点