hdu 4055 Number String(排列dp)
阿新 • • 發佈:2017-10-02
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 intView Codemain(){ 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 }
hdu 4055 Number String(排列dp)