洛谷1970 花匠(DP)
阿新 • • 發佈:2018-12-17
題意
找一個高低迴圈的最長XX序列。
題解
DP 設f[i]表示以i為結尾的最長XX序列,其中i在高位。 設g[i]表示以i為結尾的最長XX序列,其中i在低位。 這兩個可以相互轉移,即f[i]=max_{i>j,a[i]>a[j]}{g[j]}+1,同樣g也有一個轉移方程。 接下來用樹狀陣列維護一下max就可以得到50分了。
如何優化呢? 更改一下定義: 設f[i]表示前i個數字中的最長XX序列,其中i在高位。 設g[i]表示前i個數字中的最長XX序列,其中i在低位。 這樣轉移就方便很多了,f[i]=f[i-1]或者f[i]=g[i-1]+1(前提:a[i]>a[i-1]),g同理。
總結
把狀態籠統一些的表達出來(即範圍更廣),那麼轉移會更加方便。
程式碼
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=100010; int n; int a[maxn]; int f[maxn],g[maxn]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); f[1]=g[1]=1; for(int i=2;i<=n;i++) { if(a[i]>a[i-1]) f[i]=g[i-1]+1; else f[i]=f[i-1]; if(a[i]<a[i-1]) g[i]=f[i-1]+1; else g[i]=g[i-1]; } printf("%d\n",max(f[n],g[n])); return 0; }