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

题目描述

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

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

输入输出格式

输入格式:

输入文件garden.in的第1行为一个正整数n,表示需要种的树的棵树。

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

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

输出格式:

输出文件garden.out仅包括一个正整数,为最大的观赏价值和。

输入输出样例

输入样例#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[i][j][k]表示前i个已经放的树最大值,i表示当前的第i棵树,j表示当前这个i位置种的树的种类,1表示10m的,2为20m,3为30m的,k表示i这个树和前面一棵树是什么关系,1为上升,0为下降。

  由于这个花圃是个环,用约瑟夫环那样的解法未免有点大材小用,我们可以对第2~n棵树进行DP动规,最后特判一下第n棵树和第1棵树的关系与价值,取最优值即可。

  特别提示:题目中的n为1~100000,说实话真™大!我们不应该把dp数组放到主函数里面,而应该放到全局变量中,这样就不必要写高精度了O(∩_∩)O~,具体为什么,额~~自行百度把←_←

 

代码如下:

 1 #include<stdio.h>
 2 #include<string.h>
 3 int max(int a,int b)
 4 {
 5     return a>b?a:b;
 6 }
 7 int dp[100002][5][2],c[100002][5];
 8 int main()
 9 {
10     int i,j;  
11     int n,ans=0;    
12     scanf("%d",&n);
13     for(i=1;i<=n;i++) 
14     {
15         scanf("%d%d%d",&c[i][1],&c[i][2],&c[i][3]);//输入放三种树的价值 
16     }    
17     for(i=2;i<=n;i++)//寻找第2-n种情况的DP 
18     {
19         dp[i][1][1]=max(dp[i-1][2][0],dp[i-1][3][0])+c[i][1];//种10m的树与之前下降的20m树或者30m树哪个价值大 
20         dp[i][2][1]=dp[i-1][3][0]+c[i][2];//种20米的树和前面30m的树是下降状态 
21         dp[i][2][0]=dp[i-1][1][1]+c[i][2];//种20米的树和前面10m的树是上升状态 
22         dp[i][3][0]=max(dp[i-1][2][1],dp[i-1][1][1])+c[i][3];//种30m的树与之前上升的10m树或者20m树哪个价值大 
23     }
24     /*========================================*///最后对第n棵树与第1颗树来个特判即可 
25     ans=max(ans,dp[n][1][1]+c[1][2]);
26     ans=max(ans,dp[n][1][1]+c[1][3]);
27     ans=max(ans,dp[n][2][0]+c[1][1]);
28     ans=max(ans,dp[n][2][1]+c[1][3]);
29     ans=max(ans,dp[n][3][0]+c[1][1]);
30     ans=max(ans,dp[n][3][0]+c[1][2]);
31     /*========================================*/
32     printf("%d\n",ans);
33     return 0;
34 }

 

posted @ 2017-06-10 21:58  Memoryヾノ战心  阅读(533)  评论(3编辑  收藏  举报