P1133 教主的花园

题意:给出三种树,高度分别为10,20,30

    要求种n颗树,n颗树要满足当前这一颗大于相邻两颗或者小于相邻两个  (环状种植)

      每一颗树种这三种高度的观赏价值不同

        问,如何种植才最高

思路:这是一道情况多一点的简单dp;

      一开始的时候像dfs方向思考,但是因为码力不足,一时打不出来,所以改往dp方向

        不过可以肯定的是,dfs是可以实现的,只要剪枝得好

          那么接下来说说dp得做法

            我们从第二个位置开始种植,然后最后在1的这个位置计算最终答案(因为这是一个环状种植)          

              那么对于每个位置,我们需要枚举3种情况,即种植高度10,20,30这三种情况

                对于这三种情况,需要从上一个种植点转移,倘若目前种植的高度是20,那么可以选择这颗树大于周围两颗或者小于周围两颗

                  小于周围两颗的情况:我们就要从上一个种植点找到(大于周围两颗)这种情况的值进行状态转移

                  大于周围两颗的情况:我们就要从上一个种植点找到(小于周围两颗)这种情况的值进行状态转移

                    那么dp【】【】就需要开第三维,来表示当前位置是要大于周围两颗还是小于周围两颗

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 struct node
 5 {
 6     int x,y,z;
 7 }G[maxn];
 8 int dp[maxn][4][5];
 9 int main()
10 {
11     int n;
12     scanf("%d",&n);
13     for(int i=1;i<=n;i++){
14         scanf("%d%d%d",&G[i].x,&G[i].y,&G[i].z);
15     }
16     for(int i=2;i<=n;i++){
17         dp[i][1][0]=max(dp[i-1][2][1],dp[i-1][3][1])+G[i].x;
18         dp[i][2][0]=dp[i-1][3][1]+G[i].y;
19         dp[i][2][1]=dp[i-1][1][0]+G[i].y;
20         dp[i][3][1]=max(dp[i-1][2][0],dp[i-1][1][0])+G[i].z;
21     }
22     int ans=0;
23     dp[1][1][0]=max(dp[n][2][1],dp[n][3][1])+G[1].x;
24     ans=max(ans,dp[1][1][0]);
25     dp[1][2][0]=dp[n][3][1]+G[1].y;
26     ans=max(ans,dp[1][2][0]);
27     dp[1][2][1]=dp[n][1][0]+G[1].y;
28     ans=max(ans,dp[1][2][1]);
29     dp[1][3][1]=max(dp[n][2][0],dp[n][1][0])+G[1].z;
30     ans=max(ans,dp[1][3][1]);
31     printf("%d\n",ans);
32     return 0;
33 }
View Code

猜你喜欢

转载自www.cnblogs.com/pangbi/p/12565730.html