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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章