教主的花园
题目描述
教主有着一个环形的花园,他想在花园周围均匀地种上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 或 y<k>j) 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; }