CodeForces 940E
生活随笔
收集整理的這篇文章主要介紹了
CodeForces 940E
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意略。
這個題目我開始題意理解得有點問題。本題的實質是在這個數列中選擇一些數字,使得選出的這些數字之和最大,用dp來解。
我們先要明確:當我選擇數列長度為2 * c時,不如把這個長度為2 * c的劈成兩個c,這樣對答案的貢獻更大一些。
定義dp[i]為我在[i,n]中可謀取的最大貢獻。
dp[i] = max{dp[k]} + earn[i,i + c - 1] (i + c <= k <= n - c - 1)。
可用單調隊列優化。
詳見代碼:
#include<bits/stdc++.h> #define maxn 100005 using namespace std; typedef long long LL;LL ai[maxn],dp[maxn]; LL st[maxn][17],mm[maxn]; int que[maxn],head,tail,n,c;void init(){mm[0] = -1;for(int i = 1;i < maxn;++i){mm[i] = (i & (i - 1)) == 0 ? mm[i - 1] + 1 : mm[i - 1];} } void init_rmq(){for(int i = 1;i <= n;++i) st[i][0] = ai[i];for(int j = 1;j <= mm[n];++j){for(int i = 1;i + (1<<j) - 1 <= n;++i){st[i][j] = min(st[i][j - 1],st[i + (1<<(j - 1))][j - 1]);}} } LL rmq(int l,int r){LL k = mm[r - l + 1];return min(st[l][k],st[r - (1<<k) + 1][k]); }int main(){init();while(scanf("%d%d",&n,&c) == 2){LL sum = 0;for(int i = 1;i <= n;++i){scanf("%lld",&ai[i]);sum += ai[i];}init_rmq();memset(dp,0,sizeof(dp));head = tail = 0;LL ans = 0;for(int i = n - c + 1;i >= 1;--i){dp[i] = dp[que[head]] + rmq(i,i + c - 1);ans = max(ans,dp[i]);while(head < tail && dp[que[tail - 1]] < dp[i + c - 1]) --tail;que[tail++] = i + c - 1;}printf("%lld\n",sum - ans);}return 0; }?
轉載于:https://www.cnblogs.com/tiberius/p/8537540.html
總結
以上是生活随笔為你收集整理的CodeForces 940E的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL分类、数据类型
- 下一篇: spring cloud各组件详解