题目描述
教主有着一个环形的花园,他想在花园周围均匀地种上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个位置的树相邻。
输出格式:
一个正整数,为最大的观赏价值和。
输入输出样例
4 1 3 2 3 1 2 3 1 2 3 1 2
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一定为偶数。
挺好的一道dp
一开始开了三维的 dp[i][j][k] 表示 前i个 最后一个为k 前一个为j 的最大价值 然后向后递推
只有70分 因为首尾不一定满足
然后再开一维记录首的高度即可
最后再判断一下 最后一个数是否满足 (因为知道倒数第二个和第一个)
但是还不知道首是否满足条件
题目还给了一个关键条件 n为偶数 这样一来 n-1个点满足了条件 剩下一个也必然满足条件
#includeusing namespace std;//input by bxd#define rep(i,a,b) for(int i=(a);i<=(b);i++)#define repp(i,a,b) for(int i=(a);i>=(b);--i)#define RI(n) scanf("%d",&(n))#define RII(n,m) scanf("%d%d",&n,&m)#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)#define RS(s) scanf("%s",s);#define ll long long#define pb push_back#define REP(i,N) for(int i=0;i<(N);i++)#define CLR(A,v) memset(A,v,sizeof A)//#define inf 0x3f3f3f3fconst int N=100000+5;ll dp[N][3][3][3];int n;struct node{ int v[4];}ss[N];int main(){ RI(n); rep(i,1,n) RIII(ss[i].v[1],ss[i].v[2],ss[i].v[3]); ss[n+1]=ss[1]; rep(i,1,3) rep(j,1,3) if(i!=j) dp[2][i] [i][j]=ss[1].v[i]+ss[2].v[j]; rep(i,3,n+1) { rep(fi,1,3) rep(j,1,3)//当前 rep(s,1,3)//前一位 rep(k,1,3)//再前一位 { if(j>s&&k>s||j k&&j>k ) ans=max(ans,dp[n][i][j][k] ); cout<