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;
}

posted @ 2025-10-23 10:31  bz02_2023f2  阅读(1)  评论(0)    收藏  举报  来源