之前一直在luogu博客上
2018年12月25日17:17:36 copy到博客园
P1133 教主的花园
三维dp 不好想 但是看了题解之后明白了
首先 推一下公式
只看当前位置与之前位置的关系
1. 如果当前位置种①号树 要且只能满足高矮高 前面可以种②或③号
2. 如果当前位置种②号树 要满足高矮高 前面只能种③号
2. 如果当前位置种②号树 要满足矮高矮 前面只能种①号
3. 如果当前位置种③号树 要且只能满足矮高矮 前面可以种①或②号
到这里就差不多了
主要变量:f[i][j][k] 表示第i个位置种第j棵树 k=0 表示递增 k=1 表示递减
转移公式:看代码吧 懒得打了
Code:
#include<iostream>
#include<cstdio> #include<algorithm> #define maxn 100005 using namespace std; int a[maxn][5],f[maxn][5][2],n,ans=0; int main() { cin.sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++) cin>>a[i][1]>>a[i][2]>>a[i][3]; for(int i=2;i<=n;i++) { f[i][1][1]=max(f[i-1][2][0],f[i-1][3][0])+a[i][1]; f[i][2][1]=f[i-1][3][0]+a[i][2]; f[i][2][0]=f[i-1][1][1]+a[i][2]; f[i][3][0]=max(f[i-1][2][1],f[i-1][1][1])+a[i][3]; } ans=max(ans,f[n][1][1]+a[1][2]); ans=max(ans,f[n][1][1]+a[1][3]); ans=max(ans,f[n][2][1]+a[1][3]); ans=max(ans,f[n][2][0]+a[1][1]); ans=max(ans,f[n][3][0]+a[1][1]); ans=max(ans,f[n][3][0]+a[1][2]); cout<<ans; }