zoukankan      html  css  js  c++  java
  • CodeChef-MOU2H Mountain Holidays 2 【DP】

    题目链接

    题意

    有一座山,给出山中每一点的高度。现定义爬山的方法,可以从一个点传送到另一个点,也可以移动到相邻的一个点,但两种走法都必须向右。定义爬山的一个方案是爬山的过程中在相邻点移动时产生的高度差的序列。求爬山的不同方案数。

    分析

    将这个题的模型抽象出来,这个题就等价于:不相同子序列的计数问题

    设数列为(A[i]),状态

    [dp[i] leftrightarrow 以A[i]结尾的数列的不相同子序列个数 ]

    首先若我们不考虑“不相同”这个要求,那显然有:

    [dp[i]=dp[i-1]*2 ]

    而为了去重,我们设(pre[i])为最近的一个在A[i]之前且与之相同的数的位置(当然,如果不存在就不用减),那么有:

    [dp[i]=dp[i-1]*2-dp[pre[i]-1] ]

    此外这个题必须O(n)跑,因此不要Hash或用map之类的

    AC代码

    //CodeChef-MOU2H Mountain Holidays 2
    //AC 2017-4-24
    //DP
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=2e6+1000;
    const int maxm=9e6+1000;
    const long long MOD=1e9+9;
    
    int T,N;
    long long H[maxn],dp[maxn];
    int occur[maxm],*pre=occur+(int)4e6+1000;
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&N);
            for(int i=1;i<=N;++i)
                scanf("%lld",H+i);
            for(int i=1;i<N;++i)
            {
                H[i]-=H[i+1];
                pre[H[i]]=-1;
            }
            dp[0]=1;
            for(int i=1;i<N;++i)
            {
                dp[i]=(dp[i-1]<<1)%MOD;
                if(pre[H[i]]!=-1)
                    dp[i]=(dp[i]-dp[pre[H[i]]-1]+MOD)%MOD;
                pre[H[i]]=i;
            }
            printf("%lld
    ",(dp[N-1]-1+MOD)%MOD);
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    函数与导数部分的题型梳理
    构造函数习题1
    破解构造函数问题
    函数的值域
    函数的定义域
    高三数学微课堂
    Redux Todos Example
    Linux下查看Nginx安装目录、版本号信息及当前运行的配置文件
    antd的Tree控件实现点击展开功能
    Redux Counter example
  • 原文地址:https://www.cnblogs.com/DrCarlluo/p/6763325.html
Copyright © 2011-2022 走看看