卖萌
時間限制:?1 Sec??內存限制:?128 MB
提交:?5??解決:?4
[提交] [狀態] [討論版] [命題人:admin]
題目描述
正在rainbow的城堡游玩的freda恰好看見了在地毯上跳舞賣萌的水叮當……于是……
freda:“嗚咕>_< 我也要賣萌T_T!”
rainbow給了freda N秒的自由活動時間,不過由于剛剛游覽城堡有些累了,freda只想花B秒的時間來賣萌,剩下的時間她要在rainbow的城堡里睡個好覺好好休息一下。
rainbow給這N秒每秒定義了一個值Ui,如果第i秒鐘freda在賣萌,那么她可以獲得Ui點賣萌指數lala~
freda開始賣萌后可以隨時停止,休息一會兒之后再開始。不過每次freda開始賣萌時,都需要1秒來準備= =,這一秒是不能獲得賣萌指數的。當然,freda賣萌和準備的總時間不能超過B。
更特殊的是,這N秒鐘時間是環形的。也就是freda可以從任意時間開始她的自由活動并持續N秒。
為了使自己表現得比水叮當更萌,現在freda想知道,她最多能獲得多少賣萌指數呢?
?
輸入
第一行包含兩個整數N和B。
第2~N+1行每行一個整數,其中第i+1行的整數表示Ui。
?
輸出
輸出一個整數,表示freda可以獲得的最大賣萌指數。
?
樣例輸入
5 3 2 0 3 1 4?
樣例輸出
6第一個問題怎么優化時間? 和 空間
:容易想到的處理:?
dp[i][j][0/1]前i秒賣萌j秒且第i秒不賣萌/賣萌的最大值?
dp[i][j][1]=max(dp[i-1][j-1][1]+w[i],dp[i-1][j-1][0])?
dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1])?
發現只由i-1轉移過來,可滾動
第二個問題怎么怎么處理環:
由題意知,如果第一秒賣了萌且不是準備,那么n秒必須賣萌或準備,如果第一秒沒賣萌或第一秒準備,則無所謂。?
最后只需要只賦相應的初值,分別跑一次即可。
(提供了一種思路,就是對于環,不一定要像一般的復制一個接在后面,這樣由于頭的情況不止一個(賣萌/準備),反而把問題復雜化。因為連接的情況就是頭尾一致/不一致,可以分別處理)
我的ac代碼:
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; int a[3605]; int dp[2][3605][2]; int main() {int n,b;while(~scanf("%d%d",&n,&b)){memset(a,0,sizeof(a));for(int i=1; i<=n; i++){scanf("%d",&a[i]);}memset(dp,-63,sizeof(dp));int now = 1;;int pre = 0;dp[now][1][1] = a[1];now = now^1;int ans = 0;for(int i=2; i<=n; i++){pre = now^1;for(int j=0; j<=min(i,b); j++){if(j){dp[now][j][1] = max(dp[pre][j-1][1]+a[i],dp[pre][j-1][0]);}dp[now][j][0] = max(dp[pre][j][0],dp[pre][j][1]);}now = now^1;}ans = max(ans,dp[now^1][b][1]);memset(dp,-63,sizeof(dp));now = 1;;pre = 0;dp[now][0][0] = 0;dp[now][1][1] = 0;now = now^1;for(int i=2; i<=n; i++){pre = now^1;for(int j=0; j<=min(i,b); j++){if(j){dp[now][j][1] = max(dp[pre][j-1][1]+a[i],dp[pre][j-1][0]);}dp[now][j][0] = max(dp[pre][j][0],dp[pre][j][1]);}now = now^1;}ans = max(ans,max(dp[now^1][b][1],dp[now^1][b][0]));printf("%d\n",ans);}return 0; }參考博客:https://blog.csdn.net/bfk_zr/article/details/78271472
總結
- 上一篇: Juniper防火墙session会话数
- 下一篇: CS模式网络游戏的运动同步总结