zoukankan      html  css  js  c++  java
  • HDU4055_Number String

    题目告诉你在一个排列中,相邻两个数的大小关系。问你排列可能有多少种情况。

    DP。

    f[i][j]表示将i个数按照前面i-1个大小关系排列且最后一个数位j的排列数有多少个。

    这样对于新加入的一个数i+1,我们直接枚举第i+1个数在所有的i+1个数为第几大即可。

    注意加入sum数组,不然时间复杂度就是O(N^3)了。

    注意不要每次取模,注意不需要long long。注意时间常数。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define maxn 1010
    #define M 1000000007
    using namespace std;
    
    int f[maxn][maxn],sum1[maxn],sum2[maxn];
    char s[maxn];
    
    int count(int x)
    {
        if (x<M) return x;
        return x-M;
    }
    
    int main()
    {
        while (scanf("%s",s+1)!=EOF)
        {
            memset(f,0,sizeof f);
            memset(sum1,0,sizeof sum1);
            memset(sum2,0,sizeof sum2);
            f[1][1]=1,sum1[1]=1,sum2[1]=1;
            for (int i=1; s[i]; i++)
            {
                for (int j=1; j<=i+1; j++)
                {
                    if (s[i]=='?') f[i+1][j]=count(sum1[j-1]+sum2[j]);
                    else if (s[i]=='I') f[i+1][j]=sum1[j-1];
                    else if (s[i]=='D') f[i+1][j]=sum2[j];
                }
                sum1[1]=f[i+1][1];
                for (int j=2; j<=i+1; j++) sum1[j]=count(sum1[j-1]+f[i+1][j]);
                sum2[i+1]=f[i+1][i+1];
                for (int j=i; j>0; j--) sum2[j]=count(sum2[j+1]+f[i+1][j]);
            }
            int ans=0,n=strlen(s+1)+1;
            for (int i=1; i<=n; i++) ans=count(ans+f[n][i]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    Codeforces 700A As Fast As Possible(二分答案)
    BZOJ 1196 [HNOI2006]公路修建问题(二分答案+并查集)
    Codeforces 701C They Are Everywhere(Two pointers+STL)
    Codeforces 430B Balls Game(Two Pointers)
    CSU 1812 三角形和矩形
    CSU 1804 有向无环图
    CSU 1803 2016
    CSU 1808 地铁
    CodeForces 707B Bakery
    CodeForces 707A Brain's Photos
  • 原文地址:https://www.cnblogs.com/lochan/p/3437945.html
Copyright © 2011-2022 走看看