洛谷 題解 P1133 【教主的花園】
阿新 • • 發佈:2019-05-06
代碼 etc ons c++ 是否 處理 表示 esp 題解
$n<=10^5 $
O(n)算法
- 狀態
dp[i][j][k]表示在第i個位置,種j*10的高度的樹,且這棵樹是否比相鄰兩棵樹高
- 轉移
dp[i][1][0]=max(dp[i-1][2][1],dp[i-1][3][1])+a[i]; //種高度為10的樹,肯定比相鄰的兩棵樹矮 dp[i][2][0]=dp[i-1][3][1]+b[i]; //種高度為20且高度比相鄰的矮的,那麽第i-1棵肯定是高度為30且比相鄰的兩棵高的 dp[i][2][1]=dp[i-1][1][0]+b[i]; //種高度為20且高度比相鄰的高的,那麽第i-1棵肯定是高度為10且比相鄰的兩棵矮的 dp[i][3][1]=max(dp[i-1][1][0],dp[i-1][2][0])+c[i]; //種高度為30的樹,肯定比相鄰的兩棵樹高
- 答案
取dp[n][1][0]、dp[n][2][0]、dp[n][2][1]、dp[n][3][1]的最大值
但是只有70分...
特別地,第1個位置的樹與第n個位置的樹相鄰。
這個好像沒有考慮過
所以要把位置為1的特殊處理
dp[1][1][0]=max(dp[n][2][1],dp[n][3][1])+a[1];
dp[1][2][0]=dp[n][3][1]+b[1];
dp[1][2][1]=dp[n][1][0]+b[1];
dp[1][3][1]=max(dp[n][1][0],dp[n][2][0])+c[1];
那麽答案就應該是這個:
取dp[1][1][0]、dp[1][2][0]、dp[1][2][1]、dp[1][3][1]的最大值
完整代碼:
#include<bits/stdc++.h> using namespace std; const int MAXN=100000+10; int n; int a[MAXN],b[MAXN],c[MAXN]; int dp[MAXN][4][2]; inline int read() { int tot=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') { tot=tot*10+c-'0'; c=getchar(); } return tot; } int main() { n=read(); for(int i=1;i<=n;i++) a[i]=read(),b[i]=read(),c[i]=read(); for(int i=2;i<=n;i++) { dp[i][1][0]=max(dp[i-1][2][1],dp[i-1][3][1])+a[i]; dp[i][2][0]=dp[i-1][3][1]+b[i]; dp[i][2][1]=dp[i-1][1][0]+b[i]; dp[i][3][1]=max(dp[i-1][1][0],dp[i-1][2][0])+c[i]; } dp[1][1][0]=max(dp[n][2][1],dp[n][3][1])+a[1]; dp[1][2][0]=dp[n][3][1]+b[1]; dp[1][2][1]=dp[n][1][0]+b[1]; dp[1][3][1]=max(dp[n][1][0],dp[n][2][0])+c[1]; cout<<max(dp[1][1][0],max(dp[1][2][0],max(dp[1][2][1],dp[1][3][1])))<<endl; return 0; }
洛谷 題解 P1133 【教主的花園】