1. 程式人生 > >洛谷-教主的花園-動態規劃

洛谷-教主的花園-動態規劃

是什麽 main ans i++ 約定 題目 種類 printf 狀態

題目描述

教主有著一個環形的花園,他想在花園周圍均勻地種上n棵樹,但是教主花園的土壤很特別,每個位置適合種的樹都不一樣,一些樹可能會因為不適合這個位置的土壤而損失觀賞價值。

教主最喜歡3種樹,這3種樹的高度分別為10,20,30。教主希望這一圈樹種得有層次感,所以任何一個位置的樹要比它相鄰的兩棵樹的高度都高或者都低,並且在此條件下,教主想要你設計出一套方案,使得觀賞價值之和最高。

輸入輸出格式

輸入格式:

輸入文件garden.in的第1行為一個正整數n,表示需要種的樹的棵樹。

接下來n行,每行3個不超過10000的正整數ai,bi,ci,按順時針順序表示了第i個位置種高度為10,20,30的樹能獲得的觀賞價值。

第i個位置的樹與第i+1個位置的樹相鄰,特別地,第1個位置的樹與第n個位置的樹相鄰。

輸出格式:

輸出文件garden.out僅包括一個正整數,為最大的觀賞價值和。

輸入輸出樣例

輸入樣例#1:
4 
1 3 2 
3 1 2 
3 1 2 
3 1 2
輸出樣例#1:
11

說明

【樣例說明】

第1~n個位置分別種上高度為20,10,30,10的樹,價值最高。

【數據規模與約定】

對於20%的數據,有n≤10;

對於40%的數據,有n≤100;

對於60%的數據,有n≤1000;

對於100%的數據,有4≤n≤100000,並保證n一定為偶數。

思路:

  這題是典型的三維動規,在這裏我用一個三維數組dp[i][j][k]表示前i個已經放的樹最大值,i表示當前的第i棵樹,j表示當前這個i位置種的樹的種類,1表示10m的,2為20m,3為30m的,k表示i這個樹和前面一棵樹是什麽關系,1為上升,0為下降。

  由於這個花圃是個環,用約瑟夫環那樣的解法未免有點大材小用,我們可以對第2~n棵樹進行DP動規,最後特判一下第n棵樹和第1棵樹的關系與價值,取最優值即可。

  特別提示:題目中的n為1~100000,說實話真?大!我們不應該把dp數組放到主函數裏面,而應該放到全局變量中,這樣就不必要寫高精度了O(∩_∩)O~,具體為什麽,額~~自行百度把←_←

代碼如下:

 1 #include<stdio.h>
 2 #include<string.h>
 3 int max(int a,int b)
 4 {
 5     return a>b?a:b;
 6 }
 7 int
dp[100002][5][2],c[100002][5]; 8 int main() 9 { 10 int i,j; 11 int n,ans=0; 12 scanf("%d",&n); 13 for(i=1;i<=n;i++) 14 { 15 scanf("%d%d%d",&c[i][1],&c[i][2],&c[i][3]);//輸入放三種樹的價值 16 } 17 for(i=2;i<=n;i++)//尋找第2-n種情況的DP 18 { 19 dp[i][1][1]=max(dp[i-1][2][0],dp[i-1][3][0])+c[i][1];//種10m的樹與之前下降的20m樹或者30m樹哪個價值大 20 dp[i][2][1]=dp[i-1][3][0]+c[i][2];//種20米的樹和前面30m的樹是下降狀態 21 dp[i][2][0]=dp[i-1][1][1]+c[i][2];//種20米的樹和前面10m的樹是上升狀態 22 dp[i][3][0]=max(dp[i-1][2][1],dp[i-1][1][1])+c[i][3];//種30m的樹與之前上升的10m樹或者20m樹哪個價值大 23 } 24 /*========================================*///最後對第n棵樹與第1顆樹來個特判即可 25 ans=max(ans,dp[n][1][1]+c[1][2]); 26 ans=max(ans,dp[n][1][1]+c[1][3]); 27 ans=max(ans,dp[n][2][0]+c[1][1]); 28 ans=max(ans,dp[n][2][1]+c[1][3]); 29 ans=max(ans,dp[n][3][0]+c[1][1]); 30 ans=max(ans,dp[n][3][0]+c[1][2]); 31 /*========================================*/ 32 printf("%d\n",ans); 33 return 0; 34 }

洛谷-教主的花園-動態規劃