T - Permutation 題解(思維+dp)
阿新 • • 發佈:2020-11-25
題目連結
題目大意
給你一個數字n和長為n-1個字串
字串包含'<','>'
若s[i]='<' 則代表a[i]<a[i+1]
若s[i]='>' 則代表a[i]>a[i+1]
你要構造一個長度為n的全排列,使其滿足條件
求方案數mod 1e9+7
題目思路
這個問題主要就是不知道如何保證自己構造的陣列是一個全排列
又是一個神仙dp,
設\(dp[i][j]\)代表[1,i]為全排列,且第i個元素為j
那麼該怎麼轉移。
若為'<' \(dp[i][j]=\sum_{t=1}^{t=j-1} dp[i-1][t]\)
若為‘>’ \(dp[i][j]=\sum_{t=j}^{t=n} dp[i-1][t]\)
這個轉移實屬神奇,把j放到i-1個全排列後面,然後前i-1中大於等於j的元素全部加1即可
這樣前i個元素又滿足全排列,最後一個元素還是j,滿足轉移方程
然後字首和優化即可,注意j<=i
程式碼
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<vector> #include<string> #include<cstring> #include<iostream> #include<algorithm> #define fi first #define se second #define debug printf(" I am here\n"); using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; const ll INF=0x3f3f3f3f3f3f3f3f; const int maxn=3e3+5,inf=0x3f3f3f3f,mod=1e9+7; const double eps=1e-10; int n,flag[maxn]; char s[maxn]; ll dp[maxn][maxn],pre[maxn][maxn]; int main(){ scanf("%d %s",&n,s+1); for(int i=1;i<=n-1;i++){ if(s[i]=='<'){ flag[i]=1; }else{ flag[i]=0; } } dp[1][1]=1; for(int i=1;i<=n;i++){ pre[1][i]=1; } for(int i=2;i<=n;i++){ for(int j=1;j<=n;j++){ if(j>i){ pre[i][j]=pre[i][j-1]; continue; } if(flag[i-1]){ dp[i][j]=pre[i-1][j-1]%mod; }else{ dp[i][j]=((pre[i-1][n]-pre[i-1][j-1])%mod+mod)%mod; } pre[i][j]=(pre[i][j-1]+dp[i][j])%mod; } } printf("%lld\n",pre[n][n]); return 0; }