zoukankan      html  css  js  c++  java
  • Comet OJ

    地址:https://cometoj.com/contest/76/problem/A?problem_id=4237

     

         解析:这个题用DP解比较简单,其他的解法我并没有看懂。所谓波浪,单独一个数字不能算,两个数字一定算上。我们的二维dp,j=0表示下降或相等,j =1 表示上升。i 从0到n

         转移方程:

    if(a[i-1]<=a[i])
            {
                dp[i][0]=dp[i-1][1]+1;
            }
            else
                dp[i][1]=dp[i-1][0]+1;
            sum+=dp[i][0]+dp[i][1];

       拿样例来解释一下:

       我们可以写出这么个东西:    0  1

                1       0  1   

                2       0  1  

                3       2  0

                4       1  0

          sum逐个加就是答案。   第一步,从 i =1 开始,出现上升,则dp[1][1]=dp[0][0]+1;

                        第二步,i=2 , 2->3还是上升,但是dp[2][1]不能承接上一个dp[1][1],因为三个上升数不是波浪,需要承接dp[0][1],再加1(差不多算是重置吧)

                       第三步, i =3 ,3->2,出现下降,dp[3][0]=dp[2][1]+1=2,这里说明一下,dp[2][1]存的是2->3,+1里的这个1,是新的3->2,原来的2->3接上3->2,数目还是那个数目,既dp[3][0]=dp[2][1]+1=2。      

            总的来说,这个转移方程中,+1就是加的当前新的波浪,而上一步的dp,是之前的波浪接上了此次的新波浪,数目依然是上一个dp,但是样子已经不同了,所以要用sum进行累加。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long  ll ;
    const int maxn = 3e6+10;
    int dp[maxn][2];
    int a[maxn];
    int main()
    {
        int n ;
        cin>>n;
        for(int i = 0 ; i< n ;i ++)
            cin>>a[i];
        ll sum = 0 ;
        for(int i = 1 ; i< n ; i++)
        {
            if(a[i-1]<=a[i])
            {
                dp[i][0]=dp[i-1][1]+1;
            }
            else
                dp[i][1]=dp[i-1][0]+1;
            sum+=dp[i][0]+dp[i][1];
        }    cout<<sum<<endl;
    }
  • 相关阅读:
    Java线程安全和非线程安全
    时间戳获取(周,年,月,日)
    spring+spring 日志输出
    Spring+springMvc+Mybatis
    关于mysql处理百万级以上的数据时如何提高其查询速度的方法
    Tomcat 详解
    理解 $_POST、$_GET 、php://input
    php编译参数注解--不明白许多参数的作用 慎用 –with-curlwrappers参数【转载】
    centos6.5编译安装php[整理一]
    ubuntu16.04 安装chrome 和 phpstorm
  • 原文地址:https://www.cnblogs.com/liyexin/p/12683136.html
Copyright © 2011-2022 走看看