题目:
http://acm.hdu.edu.cn/showproblem.php?pid=4055
题意:
给出一个字符串s,其中'D'代表递减,‘I’代表递增,‘?’代表任意;
s[ i ] 表示第i+1个数字相对第i个的状态;
求n个数字的排列组合满足条件的组合数;
思路:
dp,
根据 I 或 D 更新dp[i][j];
dp[i][j],表示第i个数字为j时的方案数;
如果 s[i-1] == ’I‘ ,那么 dp[i][j] = dp[i-1][j-1] + dp[i-1][j-2] + ... + dp[i-1][1]。
即在前数为1到j-1的情况和;
如果 s[i-1] == 'D',那么 dp[i][j] = dp[i-1][i-1] + dp[i-1][i-2] + ... + dp[i-1][j]。
即前数为j到i-1的这些数+1后大于j的情况和;
代码:
#define N 1123
int n,m;
int f[N][N];
int dp[N][N];
char s[101];
int main()
{
int i,j,k,kk,t,x,y;
memset(dp,0,sizeof(dp));
dp[1][1]=f[1][1]=1;
while(scanf("%s",s+1)!=EOF)
{
n=strlen(s+1)+1;
for(i=2;i<=n;i++)
for(j=1;j<=i;j++)
{
if(s[i-1] == 'I')
dp[i][j] = f[i-1][j-1];
else if(s[i-1] == 'D')
dp[i][j] = (f[i-1][i-1]-f[i-1][j-1]+MOD)%MOD;
else
dp[i][j] = f[i-1][i-1];
f[i][j] = (f[i][j-1]+dp[i][j])%MOD;
}
printf("%d\n",f[n][n]);
}
return 0;
}