DP練習1題解B
阿新 • • 發佈:2018-12-09
DP練習1題解B
先上題目描述 POJ2181
樣例輸入
8
7
2
1
8
4
3
5
6
樣例輸出
17
因為有兩個方向 如果只開一個數組dp[i],難以儲存前一步是上還是下
而考慮到只要奶牛不是傻子(其實是人不是傻子) 最後一步一定是上
那麼容易想到是不是可以用dp[i]儲存到當前最大的跳躍能量(最後一步為上)
那麼需要考慮就是下的那步 從dp[j]轉移到dp[i],下的一步應該是i到j的最小值
那就要開一個數組預處理 但看到150000我們知道只有O(n)才能救中國 肯定不行
因為之前的思路問題在無法處理下的那步狀態 那麼換個角度可以想到開兩個陣列
一個儲存當前步為下的最優子狀態,一個儲存當前步為上的最優子狀態。
我把它們命名為u[ ] d[ ]
得到狀態轉移方程:
u[i]=max(d[i-1]+a[i],u[i-1])
d[i]=max(u[i-1]+a[i],d[i-1])
眾所周知 狀態轉移方程出來 題目就做完了 因此
程式碼如下:
#include<iostream> #include<cstring> int u[150001]; int d[150001]; int a[150001]; using namespace std; int main() { int n,i; memset(a,0,sizeof(a)); memset(d,0,sizeof(d)); memset(u,0,sizeof(u)); cin>>n; cin>>a[1]; cin>>a[2]; d[2]=a[1]-a[2]; u[2]=a[1]; if (a[2]>u[2]) u[2]=a[2]; for (i=3;i<=n;i++) { cin>>a[i]; u[i]=u[i-1]; d[i]=d[i-1]; if (d[i-1]+a[i]>u[i]) u[i]=d[i-1]+a[i]; if (u[i-1]-a[i]>d[i]) d[i]=u[i-1]-a[i]; } cout<<u[n]<<endl; }
以上