1. 程式人生 > >hdu 4055 Number String(排列dp)

hdu 4055 Number String(排列dp)

con open 詳細 序列 ons src efi com html

題目鏈接:hdu 4055 Number String

題意:

給你一個長度為n的指定的升降序列,問有多少種排列,符合這樣的序列。

題解:

訓練賽的時候沒想出來,大概這種排列的dp需要轉換一下思維吧。

考慮dp[i][j]表示前i個數只用1~i,結尾為j。

然後就有

如果s[i - 1]是‘ I ‘,那麽dp[i][j] = dp[i-1][j-1] + dp[i-1][j-2] + .. + dp[i-1][1]。

如果s[i - 1]是‘D’,那麽dp[i][j] = dp[i-1][j] + dp[i-1][j+1] + ... + dp[i-1][i]。

如果s[i - 1]是‘?’,那麽dp[i][j] = dp[i-1][i-1] + ... + dp[i-1][1]。

比較巧妙。需要好好想想,詳細題解:傳送門

技術分享
 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 3 using namespace std;
 4 #define mst(a,b) memset(a,b,sizeof(a))
 5 
 6 const int N=1007,P=1e9+7;
 7 char s[N];
 8 int dp[2][N],n,x;
 9 
10 void up(int &a,int b){a+=b;if(a>=P)a-=P;}
11 
12 int
main(){ 13 while(~scanf("%s",s+1)) 14 { 15 n=strlen(s+1)+1; 16 mst(dp,0),dp[x=0][1]=1; 17 F(i,2,n) 18 { 19 x^=1,mst(dp[x],0); 20 if(s[i-1]==?) 21 { 22 F(j,1,i-1)up(dp[x][1],dp[x^1][j]); 23 F(j,2
,i)up(dp[x][j],dp[x][1]); 24 } 25 else if(s[i-1]==I) 26 { 27 F(j,1,i)up(dp[x][j],dp[x][j-1]+dp[x^1][j-1]); 28 } 29 else 30 { 31 for(int j=i;j;j--) 32 up(dp[x][j],dp[x][j+1]+dp[x^1][j]); 33 } 34 } 35 int ans=0; 36 F(i,1,n)up(ans,dp[x][i]); 37 printf("%d\n",ans); 38 } 39 return 0; 40 }
View Code

hdu 4055 Number String(排列dp)