zoukankan      html  css  js  c++  java
  • 洛谷-教主的花园-动态规划

    题目描述

    教主有着一个环形的花园,他想在花园周围均匀地种上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
    ",ans);
    33     return 0;
    34 }
  • 相关阅读:
    在Ubuntu中通过update-alternatives切换软件版本
    SCons: 替代 make 和 makefile 及 javac 的极好用的c、c++、java 构建工具
    mongodb 的使用
    利用grub从ubuntu找回windows启动项
    How to Repair GRUB2 When Ubuntu Won’t Boot
    Redis vs Mongo vs mysql
    java script 的工具
    python 的弹框
    how to use greendao in android studio
    python yield的终极解释
  • 原文地址:https://www.cnblogs.com/geek-007/p/6980115.html
Copyright © 2011-2022 走看看