zoukankan      html  css  js  c++  java
  • B(升降序列)

    B(升降序列)

    pic


    题目

    【题目描述】

    对于一个排列,考虑相邻的两个元素,如果后面一个比前面一个大,表示这个位置是上升的,用 I 表示,反之这个位置是下降的,用 D 表示。如排列 3,1,2,7,4,6,5 可以表示为 DIIDID。

    现在给出一个长度为 n-1 的排列表示,问有多少种 1 到 n 的排列满足这种表示。

    【输入输出格式】

    输入格式:
    一个字符串 S,S 由 I,D,?组成。?表示这个位置既可以为 I,又可以为 D。

    输出格式:
    有多少种排列满足上述字符串。输出排列数模 1000000007。

    【输入输出样例】

    输入样例#1:
    ?D
    输出样例#1:
    3
    【说明】
    对于 20%的数据,S 长度 ≤ 10;
    对于 100%的数据,S 长度 ≤ 1000。

    思路

    dp。
    (dp[i][j])表示i这么长的序列,最后一个是j的符合要求的序列个数
    于是有方程:

    [dp_{i,j}= egin{cases} sum_{k=1}^{j-1} dp_{i-1,k} ext{Order='I'} \[1ex] \ sum_{k=j}^{i-1} dp_{i-1,k} ext{Order='D'}end{cases} ]

    为了简化计算,计算(dp_{i,...})之前,把(dp_{i-1,...})处理成前缀和的形式。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define mod 1000000007
    #define LL long long
    #define File freopen("B.in","r",stdin);freopen("B.out","w",stdout)
    using namespace std;
    const int maxn=1000+5;
    
    LL n=1,dp[maxn][maxn],ans;
    char c;
    
    int main() {
        ios::sync_with_stdio(false);
    //    File;
        c=getchar();
        dp[1][1]=1;
        while(c=='?' || c=='D' || c=='I') {
            n++;
            for(LL i=1; i<n; ++i) {
                dp[n-1][i]=(dp[n-1][i]+dp[n-1][i-1])%mod;
            }
            if(c=='I') {
                for(LL i=2; i<=n; ++i)
                    dp[n][i]=dp[n-1][i-1]%mod;
            }
            if(c=='D') {
                for(LL i=1; i<n; ++i) {
                    dp[n][i]=(dp[n-1][n-1]-dp[n-1][i-1]+mod)%mod;
                }
            }
            if(c=='?') {
                for(LL i=2; i<=n; ++i) {
                    dp[n][i]=dp[n-1][i-1]%mod;
                }
                for(LL i=1; i<n; ++i) {
                    dp[n][i]+=(dp[n-1][n-1]-dp[n-1][i-1]+mod)%mod;
                }
            }
            c=getchar();
        }
        ans=0;
        for(LL i=1; i<=n; ++i) {
            ans+=dp[n][i];
            ans=ans%mod;
        }
        cout<<ans%mod;
        return 0;
    }
    
    
  • 相关阅读:
    友元类和友元函数
    C++中构造函数和析构函数调用的时机
    Linux 下svn恢复到某一版本
    lua 中pairs 和 ipairs区别
    孤儿进程与僵尸进程
    union
    关于C++ const 的全面总结
    后台管理左侧菜单
    全选-反选-取消
    Dom-直接 /间接选择器
  • 原文地址:https://www.cnblogs.com/YQAccelerator/p/7413783.html
Copyright © 2011-2022 走看看