1. 程式人生 > >不等式數列 DP

不等式數列 DP

tac %d question def des scanf 位置 using class

度度熊最近對全排列特別感興趣,對於1到n的一個排列,度度熊發現可以在中間根據大小關系插入合適的大於和小於符號(即 ‘>‘ 和 ‘<‘ )使其成為一個合法的不等式數列。但是現在度度熊手中只有k個小於符號即(‘<‘‘)和n-k-1個大於符號(即‘>‘),度度熊想知道對於1至n任意的排列中有多少個排列可以使用這些符號使其為合法的不等式數列。
輸入描述:
輸入包括一行,包含兩個整數n和k(k < n ≤ 1000)


輸出描述:
輸出滿足條件的排列數,答案對2017取模。

輸入例子:
5 2

輸出例子:
66
題解:
  我們考慮用dp[i][j]表示1-i這i個數字,裏面的i-1個空隙裏有j個小於號,i-j-1個大於號的方案數   兩邊很好考慮,如果插入中間某個位置的話,必然會在兩邊有一個小於號和一個大於號 那麽枚舉這個位置原來是什麽號就知道哪個號多了一個辣!
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define
pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18+1LL; const double Pi = acos(-1.0); const int N = 1e3+10, M = 1e3+20, mod = 2017,inf = 2e9; int n,k; LL dp[N][N]; int main(){ scanf("%d%d",&n,&k); dp[1][0] = 1; for(int i = 1; i <= n; ++i) {
for(int j = 0; j < i; ++j) { dp[i+1][j] += dp[i][j]*(j+1); dp[i+1][j] %= mod; dp[i+1][j+1] += dp[i][j]*(i-1-j+1); dp[i+1][j+1] %= mod; } } printf("%lld\n",dp[n][k]); return 0; }

不等式數列 DP