题目描述
教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价值。
教主最喜欢33种树,这3种树的高度分别为10,20,3010,20,30。教主希望这一圈树种得有层次感,所以任何一个位置的树要比它相邻的两棵树的高度都高或者都低,并且在此条件下,教主想要你设计出一套方案,使得观赏价值之和最高。
输入格式
第一行为一个正整数nn,表示需要种的树的棵树。
接下来nn行,每行33个不超过1000010000的正整数a_i,b_i,c_iai,bi,ci,按顺时针顺序表示了第ii个位置种高度为10,20,3010,20,30的树能获得的观赏价值。
第ii个位置的树与第i+1i+1个位置的树相邻,特别地,第11个位置的树与第nn个位置的树相邻。
输出格式
一个正整数,为最大的观赏价值和。
输入输出样例
输入 #1复制
4
1 3 2
3 1 2
3 1 2
3 1 2
输出 #1复制
11
说明/提示
【样例说明】
第11至nn个位置分别种上高度为20,10,30,1020,10,30,10的树,价值最高。
【数据规模与约定】
对于20%20%的数据,有n≤10n≤10;
对于40%40%的数据,有n≤100n≤100;
对于60%60%的数据,有n≤1000n≤1000;
对于100%100%的数据,有4≤n≤1000004≤n≤100000,并保证nn一定为偶数。
感悟“
把教主打死,乱砍乱种
令f[i][j][k][first]为在第i个位置,本位置选了第j种树,前一个位置选第k种树,第一棵树种的是first时的最大观赏值!
f[i][j][k][first]=(所有y>k<j 或 yj) max(f[i-1][k][y][first]+v[i][j]) !
然后特殊判断(n-1)位置、n位置、1位置是否满足!
#include<cstdio>
#include<iostream>
using namespace std;
int f[100010][4][4][4];
int v[100010][4];
int i,j,x,y,z,p,l,maxv=0;
int main(){
int n;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d %d %d",&v[i][1],&v[i][2],&v[i][3]);
}
for(i=1;i<4;i++){
for(j=1;j<4;j++){
f[0][i][j][i]=v[0][i];
}
}
for(i=1;i<n;i++){
for(j=1;j<4;j++){
for(x=1;x<4;x++){
for(y=1;y<4;y++){
for(z=1;z<4;z++){
if((y>x&&x<j)||(y<x&&x>j)){
f[i][j][x][z]=max(f[i][j][x][z],f[i-1][x][y][z]+v[i][j]);
}
}
}
}
}
}
for(j=1;j<4;j++){
for(p=1;p<4;p++){
for(l=1;l<4;l++){
if((p<j&&j>l)||(p>j&&j<l)){
maxv=max(maxv,f[n-1][j][p][l]);
}
}
}
}
printf("%d",maxv);
return 0;
}