zoukankan      html  css  js  c++  java
  • P1133 教主的花园 dp

      

    题目描述

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

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

    输入输出格式

    输入格式:

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

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

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

    输出格式:

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

    输入输出样例

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

    说明

    【样例说明】

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

    【数据规模与约定】

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

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

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

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

    挺好的一道dp   

    一开始开了三维的   dp[i][j][k] 表示  前i个  最后一个为k  前一个为j   的最大价值 然后向后递推

    只有70分  因为首尾不一定满足

    然后再开一维记录首的高度即可

    最后再判断一下  最后一个数是否满足  (因为知道倒数第二个和第一个) 

    但是还不知道首是否满足条件   

    题目还给了一个关键条件  n为偶数  这样一来 n-1个点满足了条件  剩下一个也必然满足条件

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=100000+5;
    ll dp[N][3][3][3];
    int n;
    struct node
    {
        int v[4];
    }ss[N];
    
    int main()
    {
        RI(n);
        rep(i,1,n)
        RIII(ss[i].v[1],ss[i].v[2],ss[i].v[3]);
    
        ss[n+1]=ss[1];
    
        rep(i,1,3)
        rep(j,1,3)
        if(i!=j)
        dp[2][i] [i][j]=ss[1].v[i]+ss[2].v[j];
    
        rep(i,3,n+1)
        {
            rep(fi,1,3)
            rep(j,1,3)//当前
            rep(s,1,3)//前一位
            rep(k,1,3)//再前一位
            {
                if(j>s&&k>s||j<s&&k<s)
                dp[i][fi][s][j]=max(dp[i][fi][s][j],dp[i-1][fi][k][s]+ss[i].v[j]);
            }
        }
        ll ans=0;
    
        rep(i,1,3)
        rep(j,1,3)
        rep(k,1,3)
        if( i<k&&j<k||i>k&&j>k )
        ans=max(ans,dp[n][i][j][k] );
        cout<<ans;
    
        return 0;
    }
    View Code
  • 相关阅读:
    VCSA 6.5 升级 VCSA 6.7
    使用再生龙Clonezilla备份还原Linux系统
    gulp前端自动化构建工具学习笔记(mac)
    Echarts基本图表的学习笔记
    jQuery中$.ajax()用法
    jQuery实现淡入淡出轮播图带左右按钮及下方小圆点
    js解析XMl文件,兼容IE、Firefox、谷歌
    HTML<marquee>标签实现滚动公告通知、广告的效果
    画太极
    让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法
  • 原文地址:https://www.cnblogs.com/bxd123/p/10862889.html
Copyright © 2011-2022 走看看