教主的花园

Posted kanchuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了教主的花园相关的知识,希望对你有一定的参考价值。

题目描述

教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价值。

教主最喜欢3种树,这3种树的高度分别为10,20,30。教主希望这一圈树种得有层次感,所以任何一个位置的树要比它相邻的两棵树的高度都高或者都低,并且在此条件下,教主想要你设计出一套方案,使得观赏价值之和最高。

 

输入输出格式

输入格式:

第一行为一个正整数n,表示需要种的树的棵树。

接下来n行,每行3个不超过1000010000的正整数a_i,b_i,c_i,按顺时针顺序表示了第ii个位置种高度为10,20,30的树能获得的观赏价值。

i个位置的树与第i+1个位置的树相邻,特别地,第1个位置的树与第n个位置的树相邻。

输出格式:

一个正整数,为最大的观赏价值和。

 

输入输出样例

输入样例#1: 
4 
1 3 2 
3 1 2 
3 1 2 
3 1 2
输出样例#1: 
11

说明

【样例说明】

1至n个位置分别种上高度为20,10,30,10的树,价值最高。

【数据规模与约定】

对于20%的数据,有n≤10

对于40%的数据,有n≤100

对于60%的数据,有n≤1000

对于100%的数据,有4≤n≤100000,并保证n一定为偶数。

 

分析:

本题较为麻烦,主要原因还是二维DP无法转移,需要扩展为较为少见的三维DP。

状态转移方程是:

f[j][0][0]=max(f[j-1][1][1],f[j-1][2][1])+a[j][0];

f[j][1][0]=f[j-1][2][1]+a[j][1];

f[j][1][1]=f[j-1][0][0]+a[j][1];

f[j][2][1]=max(f[j-1][1][0],f[j-1][0][0])+a[j][2];

 

CODE:

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 int n;
 8 int a[100005][3];
 9 int f[100005][3][2];
10 int ans;
11 inline int get()
12     char c=getchar();
13     int res=0;
14     while (c<0||c>9) c=getchar();
15     while (c>=0&&c<=9)
16         res=(res<<3)+(res<<1)+c-0;
17         c=getchar();
18     
19     return res;
20 
21 int main()
22     n=get();
23     for(int i=1;i<=n;i++)
24         a[i][0]=get();
25         a[i][1]=get();
26         a[i][2]=get();
27     
28     for(int i=0;i<3;i++)
29         for(int j=0;j<3;j++)
30             for(int k=0;k<2;k++)
31                 f[1][j][k]=0;
32             
33         
34         f[1][i][0]=f[1][i][1]=a[1][i];
35         for(int j=2;j<=n;j++)
36             f[j][0][0]=max(f[j-1][1][1],f[j-1][2][1])+a[j][0];
37             f[j][1][0]=f[j-1][2][1]+a[j][1];
38             f[j][1][1]=f[j-1][0][0]+a[j][1];
39             f[j][2][1]=max(f[j-1][1][0],f[j-1][0][0])+a[j][2];
40         
41         for(int j=0;j<i;j++) ans=max(ans,f[n][j][0]);
42         for(int j=2;j>i;j--) ans=max(ans,f[n][j][1]);
43     
44     printf("%d\n",ans);
45     return 0;
46 

 

以上是关于教主的花园的主要内容,如果未能解决你的问题,请参考以下文章

教主的花园

教主的花园 dp

洛谷-教主的花园-动态规划

P1133 教主的花园

洛谷教主花园dp

洛谷P1133 教主的花园