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;
    }
    
    
    
  • 相关阅读:
    B+树的Copy-on-Write设计
    so库链接和运行时选择哪个路径下的库?
    Xapian索引-文档检索过程分析之匹配百分比
    Xapian索引-文档检索过程分析
    Xapian的内存索引-添加文档
    Xapian的内存索引
    Xapian使用入门
    一个std::sort 自定义比较排序函数 crash的分析过程
    编译GCC4.8.2
    使用C++11的一点总结
  • 原文地址:https://www.cnblogs.com/DrCarlluo/p/6763325.html
Copyright © 2011-2022 走看看