AT_dp_t Permutation题解
题目描述
给定一个正整数 N 和一个由小于号 < 和大于号 > 组成的长度为 N−1 的字符串 s。
你需要找到一个排列 (p1, p2, p3, ..., pN),满足对于任意 i (1≤i≤N−1),如果 si 为 < 则 pi<pi+1,如果 si 为 > 则 pi>pi+1。求满足性质的排列 p 的方案数对 109+7 取模后的值。
输入格式
请按照以下格式输入:
N
s
输出格式
输出满足条件的方案个数对 109+7 取模后的值。
显示翻译
题意翻译
输入输出样例
输入 #1复制
4 <><
输出 #1复制
5
输入 #2复制
5 <<<<
输出 #2复制
1
输入 #3复制
20 >>>><>>><>><>>><<>>
输出 #3复制
217136290
说明/提示
数据范围与约定
- N 是正整数
- 2≤N≤3000
- s 是一个长度为 N−1 的字符串
- 字符串 s 包含字符
<和>
样例解释 1
有 5 个满足条件的排列,分别是:
- (1, 3, 2, 4)
- (1, 4, 2, 3)
- (2, 3, 1, 4)
- (2, 4, 1, 3)
- (3, 4, 1, 2)
样例解释 2
有 1 个满足条件的排列 (1, 2, 3, 4, 5)。
样例解释 3
注意输出结果要对 109+7 取模。
思路
DP即可。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long n,a[3001],f[3001][3001],f2[3001][3001],fg=0,mod=1e9+7;
char ch[3001];
int main(){
cin>>n;
for(int i=1;i<=n-1;i++){
cin>>ch[i];
}
f[1][1]=1;
f2[1][1]=1;
for(int i=2;i<=n;i++){
for(int j=1;j<=i;j++){
if(ch[i-1]=='<'){
f[i][j]+=f2[i-1][j-1];
}
else{
f[i][j]+=(f2[i-1][i-1]-f2[i-1][j-1]);
}
f[i][j]%=mod;
f2[i][j]=f2[i][j-1]+f[i][j];
//cout<<i<<" "<<j<<" "<<f[i][j]<<endl;
}
}
for(int i=1;i<=n;i++){
fg+=f[n][i];
}
cout<<fg%mod<<endl;
return 0;
}

浙公网安备 33010602011771号