这道题本来看见有环,以为和环有关,要拆环,后来发现根本不用,这一个的状态只和前一个有关,只会影响后一个,所以一遍推过去就好啦。。。
f[i][j][k]表示前i个,第i个种第j种树(10,20,30),k表示比前一个高(0),还是矮(1)。
这里我用了一个很笨的方法来处理第一个与第N个的关系……
就是硬性规定第一个种什么样的树,分四种情况10比n矮的,20比n高,20比n矮,30比n高,分别比较答案。
代码:
#include
#include
#include
using namespace std;
int high[110000][5],f[110000][5][2],ans,n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&high[i][1],&high[i][2],&high[i][3]);
memset(f,0,sizeof(f));
f[1][1][1]=high[1][1];
for(int i=2;i<=n;i++){
f[i][1][1]=max(f[i-1][2][0],f[i-1][3][0])+high[i][1];
f[i][2][1]=f[i-1][3][0]+high[i][2];
f[i][2][0]=f[i-1][1][1]+high[i][2];
f[i][3][0]=max(f[i-1][2][1],f[i-1][1][1])+high[i][3];
}
ans=max(ans,max(f[n][2][0],f[n][3][0]));
memset(f,0,sizeof(f));
f[1][2][1]=high[1][2];
for(int i=2;i<=n;i++){
f[i][1][1]=max(f[i-1][2][0],f[i-1][3][0])+high[i][1];
f[i][2][1]=f[i-1][3][0]+high[i][2];
f[i][2][0]=f[i-1][1][1]+high[i][2];
f[i][3][0]=max(f[i-1][2][1],f[i-1][1][1])+high[i][3];
}
ans=max(ans,f[n][3][0]);
memset(f,0,sizeof(f));
f[1][2][0]=high[1][2];
for(int i=2;i<=n;i++){
f[i][1][1]=max(f[i-1][2][0],f[i-1][3][0])+high[i][1];
f[i][2][1]=f[i-1][3][0]+high[i][2];
f[i][2][0]=f[i-1][1][1]+high[i][2];
f[i][3][0]=max(f[i-1][2][1],f[i-1][1][1])+high[i][3];
}
ans=max(ans,f[n][1][1]);
memset(f,0,sizeof(f));
f[1][3][0]=high[1][3];
for(int i=2;i<=n;i++){
f[i][1][1]=max(f[i-1][2][0],f[i-1][3][0])+high[i][1];
f[i][2][1]=f[i-1][3][0]+high[i][2];
f[i][2][0]=f[i-1][1][1]+high[i][2];
f[i][3][0]=max(f[i-1][2][1],f[i-1][1][1])+high[i][3];
}
ans=max(ans,max(f[n][1][1],f[n][2][1]));
printf("%d",ans);
return 0;
}