题意:给出三种树,高度分别为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 }