P2401 不等数列

P2401 不等数列

传送门

思路:这个数据k<n1e3k<n\leq1e3。显然可以考虑dpdp

dp[i][j]dp[i][j]表示前ii个数有jj个小于号的排列数。

假设我们已知前i1i-1个数所有情况。

接下来我们需要插入第ii个数,我们有ii个位置插入。

对于最左边和最右边,显然是增加一个大于号和小于号。

对于其他位置:1.插入到大于号的位置:显然小于号增加一个(x>y)(x<i>y)(x>y)\rightarrow(x<i>y)

2.插入到小于号的位置:(x<y)(x<i>y)(x<y)\rightarrow (x<i>y),大于号增加一个。

因此小于号的个数只会是非减的。

于是有dp[i][j]=dp[i1][j]×(j+1)dp[i][j]=dp[i-1][j]\times (j+1)

(j+1)(j+1)表示有(j+1)(j+1)个位置插入后小于号的数目不变,即最左边和jj个大于号的位置。

2.dp[i][j]=dp[i1][j1]×(ij)2.dp[i][j]=dp[i-1][j-1]\times(i-j)。表示(ij)(i-j)位置插入后小于号个数增加一个,(i[(j1)+1])=(ij)(i-[(j-1)+1])=(i-j),有(j1)+1(j-1)+1个位置是小于号个数不变。

则另外(ij)(i-j)个位置是使小于号加1.

综上dp[i][j]=dp[i1]×(j+1)+dp[i1][j1]×(ij)dp[i][j]=dp[i-1]\times(j+1)+dp[i-1][j-1]\times(i-j)

时间复杂度:O(kn)O(kn)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=1e6+5,inf=0x3f3f3f3f,mod=2015;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
int dp[N][N],n,k; 
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++) dp[i][0]=1;
	for(int i=2;i<=n;i++)
		for(int j=1;j<=min(i-1,k);j++)
			dp[i][j]=(dp[i-1][j]*(j+1)+dp[i-1][j-1]*(i-j))%mod;
	printf("%d\n",dp[n][k]); 
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章