hdu 4055 Number String

题意:给出一个字符串,问1~n这n个数中有多少种排列满足给定字符串的要求,字符串str[i]=='I'代表第i位数字要比它前一位大,str[i]=='D'代表第i位数字要比它前一位小,str[i]=='?'代表第i位数字任意。


思路:刚开始没想出怎么做,看了看题解,感觉大体思路还是能看懂的,但是细节的地方怎么也没看明白,我理解能力是有多差Orz……后来没办法了,自己YY过了,果然还是自己想的思路好写。我的思路是这样的:在1~n中拿走任意一个数,剩下的数其实可以重新编号(1~n-1),所以每一次选的时候也可以看成是一个1~k(k是当前剩下的数)的数选一个。这样的话,第i次选的数就取决于第i-1次选的数在它剩下的数中的位置了。用dp[i][j]表示到第i位时,在剩下的数中选第j个数的排列的个数。这样的话状态转移方程很容易就能列出来:如果str[i]=='I',dp[i][j]=sum{dp[i-1][1]~dp[i-1][j]},如果str[i]=='D',dp[i][j]=sum{dp[i-1][j+1]~dp[i-1][k]}(k是到i-1位时剩余的数)。这题数组开long long 的话居然会超时,这数据……不能多说。


代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=1000+10;
const int mod=1000000007;
char str[maxn];
int dp[maxn][maxn],sum[maxn][maxn];
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n;
    while(~scanf("%s",str))
    {
        n=strlen(str);
        n++;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;++i) sum[i][0]=0;
        for(int i=1;i<=n;++i)
        {
            dp[1][i]=1;
            sum[1][i]=i;
        }
        for(int i=2;i<=n;++i)
        {
            for(int j=1;j<=n-i+1;++j)
            {
                if(str[i-2]=='I'||str[i-2]=='?')
                  dp[i][j]+=sum[i-1][j]-sum[i-1][0];
                if(str[i-2]=='D'||str[i-2]=='?')
                  dp[i][j]+=sum[i-1][n-i+2]-sum[i-1][j];
                dp[i][j]%=mod;
                sum[i][j]=(sum[i][j-1]+dp[i][j])%mod;
            }
        }
        int res=(dp[n][1]+mod)%mod;
        printf("%d\n",res);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值