HDU 4055 Number String

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhlbjtu2016/article/details/82597486

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4055

题意:给了一组字符串包含'?','I','D'。'I'代表当前字符比后一个字符大,'D'代表当前字符比后一个字符小,'?'则都可以。询问有多少个这样的排列(包含1-n+1,n为字符串的长度)

分析:递推。有两种情况

第一种是第i个为I(小于号,升序):dp[i][j] = dp[i-1][j-1] + dp[i-1][j-2] + .. + dp[i-1][1]

另一种是第i个为D(大于号,降序): dp[i][j] = dp[i-1][i] + dp[i-1][i-1] + ... + dp[i-1][j]

注意第二种情况如果当前位为j,前面出现过j,则前面所有的数都要加上1,也满足条件,其余细节看代码注释

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
const int mod = 1000000007;
typedef long long ll;
char s[maxn];
ll sum[maxn][maxn];
int main()
{
    while(~scanf("%s",s))
    {
        int len = strlen(s);
        memset(sum,0,sizeof(sum));
        sum[0][1] = 1;//0个符合有数字为1的情况只有1种
        for(int i = 1; i <= len; i++)//对于len个符号有len+1个数字组成
        {
            if(s[i - 1] == 'I')//第i个符号为'I',代表第i个数字到第i+1个数字是递增的
            {
                for(int j = 1; j <= i + 1; j++)//i个符号,有i+1个数字,最后一个数字为j的所有情况由之前的递推得到
                {
                    sum[i][j] = sum[i][j - 1];//i个符号,最后一个数字为j-1的情况之前算过,最后一个数字为j的情况包含最后一个数字为j-1的情况
                    sum[i][j] = (sum[i - 1][j - 1] + sum[i][j]) % mod;//i-1个符号,最后一个数字是j-1的情况也算过,最后一个数字为j的话一定满足递增
                }
            }
            else if(s[i - 1] == 'D')//第i个符号为'D',代表第i个数字到第i+1个数字是递减的
            {
                for(int j = i + 1; j > 0; j--)//i个符号,有i+1个数字,最后一个数字为j的所有情况由之前的递推得到
                {
                    sum[i][j] = sum[i][j + 1];//i个符号,最后一个数字为j+1的情况之前算过,最后一个数字为j的情况包含最后一个数字为j+1的情况
                    sum[i][j] = (sum[i - 1][j] + sum[i][j]) % mod;//i-1个符号,最后一个数字是j+1的情况也算过,最后一个数字为j的话一定满足递减
                }
            }
            else//第i个符号是'?',则第i个数字啥都可以
            {
                ll tmp = 0;
                for(int j = 1; j <= i; j++)
                    tmp += sum[i - 1][j] % mod;
                for(int j = 1; j <= i + 1; j++)//i个符号,i+1个数字,最后一个数字无论是什么都加上i-1个符号的所有情况
                    sum[i][j] = tmp;
            }
        }
        ll ans = 0;
        for(int i = 1; i <= len + 1; i++)//长度为len+1最后一位是1-len+1的所有情况
            ans += sum[len][i] % mod;
        cout<<ans % mod<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhlbjtu2016/article/details/82597486
今日推荐