【P1326】超级教主
DP優(yōu)化
原題:
LHX教主很能跳,因?yàn)镺rz他的人太多了。教主跳需要消耗能量,每跳1米就會(huì)消耗1點(diǎn)能量,如果教主有很多能量就能跳很高。
教主為了收集能量,來到了一個(gè)神秘的地方,這個(gè)地方凡人是進(jìn)不來的。在這里,教主的正上方每100米處就有一個(gè)能量球(也就是這些能量球位于海拔100,200,300……米處),每個(gè)能量球所能提供的能量是不同的,一共有N個(gè)能量球(也就是最后一個(gè)能量球在N×100米處)。教主為了想收集能量,想跳著吃完所有的能量球。教主可以自由控制他每次跳的高度,接著他跳起把這個(gè)高度以下的能量球都吃了,他便能獲得能量球內(nèi)的能量,接著吃到的能量球消失。教主不會(huì)輕功,教主不會(huì)二段跳,所以教主不能因新吃到的能量而變化此次跳躍的高度。并且教主還是生活在地球上的,所以教主每次跳完都會(huì)掉下來。
問教主若要吃完所有的能量球,最多還能保留多少能量。
N≤2000000?
保證對(duì)于所有數(shù)據(jù),教主都能吃到所有的能量球,并且能量球包含的能量之和不超過2^31-1。
?
sum[i]表示a[i]的前綴和,很容易推出狀態(tài)轉(zhuǎn)移方程:f[i]=max{j<i && f[j]>=i*100 | f[j]+sum[i]-sum[j]-i*100}
但是數(shù)據(jù)達(dá)到2000000,n^2會(huì)T,這是后就要優(yōu)化
DP優(yōu)化方法有很多,常用的是記錄可行決策然后二分,單調(diào)隊(duì)列,斜率優(yōu)化,我這么弱斜率優(yōu)化當(dāng)然不會(huì),這題似乎不符合單調(diào)性質(zhì),所以我們搞單調(diào)隊(duì)列
上面的狀態(tài)轉(zhuǎn)移方程↑中sum[i]-i*100是不會(huì)變的,需要考慮的就是f[j]-sum[j]
就可以維護(hù)單調(diào)隊(duì)列:如果f[i]>f[隊(duì)頭]就進(jìn)隊(duì),f[j]<i*100的出對(duì),然后在隊(duì)里找就行了
然而依舊會(huì)T
書上說f[i]-s[i]單調(diào)遞減的,過程比較長,有興趣的同學(xué)可以試著自己推到(逃
又因?yàn)閕*100是單調(diào)遞增的,所以只需要記錄一個(gè)temp表示上一個(gè)用到的決策點(diǎn),從temp往后找到一個(gè)f[j]>=i*100就行了
因?yàn)閒[j]-sum[j]單調(diào)遞減且i*100單調(diào)遞增,所以如果有f[j]>=i*100的f[j]>=(i-1)*100也肯定滿足,因此從直接從temp開始找就行了,不用管temp前面的
單調(diào)性這種東西給數(shù)據(jù)打個(gè)表比較容易發(fā)現(xiàn),優(yōu)化DP時(shí)打個(gè)表挺好的
代碼;
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 int read(){int z=0,mark=1; char ch=getchar(); 8 while(ch<'0'||ch>'9'){if(ch=='-')mark=-1; ch=getchar();} 9 while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0'; ch=getchar();} 10 return z*mark; 11 } 12 int n,m,a[2100000]; 13 int sum[2100000]; 14 int f[2100000]; 15 int temp; 16 int main(){//freopen("ddd.in","r",stdin); 17 memset(f,0,sizeof(f)); 18 cin>>n>>m; 19 sum[0]=0; 20 for(int i=1;i<=n;i++){ a[i]=read(); sum[i]=a[i]+sum[i-1];} 21 f[0]=m; temp=0; 22 for(int i=1;i<=n;i++){ 23 for(;temp<i;temp++)if(f[temp]>=i*100) break; 24 f[i]=f[temp]+sum[i]-sum[temp]-i*100; 25 } 26 cout<<f[n]<<endl; 27 return 0; 28 } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/JSL2018/p/5861687.html
總結(jié)
以上是生活随笔為你收集整理的【P1326】超级教主的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CssVariables_01
- 下一篇: java9-6 内部类