【7.10校內test】T2不等數列

【題目連接luogu】c++

此題在luogu上模數是2015,考試題的模數是2012。測試

而後這道題據說好多人是打表找規律的(就像7.9T2同樣)(手動滑稽_gc)spa

另外手動設計

sy,每次測試都無心之間bibi正解,而後說本身是不會作是個什麼騷氣操做。code

因此咱們來看真.題解;blog

SOLUTION:get

首先,輸入莫得什麼好說的;it

固然想用快讀咱也攔不住(就是想用咬我啊);io

咱可能最近由於學長講了一道DP,印象比較深入,因此咱竟然看到這道題就想到正解應該是DP了!?class

接下來就是設計DP狀態了:

dp[i][j]表示i個數,恰有j個‘<’的排列方案數;

轉移就很神奇頗有意思了:

當咱們已知dp[1~i-1][1~k]時,咱們考慮求dp[i][j];

當數從i-1~i時,顯然數列增長的數是大於1~i-1的(莫得由於什麼,很差解釋,感性理解);咱們考慮把i這個數加在哪裏:

①加在序列的最左側:

由於i>1~i-1的任何一個數,因此必定是‘>’,所以對‘<’的多少沒有影響;

②加在序列最右側:

同理由於i>1~i-1任何一個數,因此當將i放在序列最右側時,必定會增長一個‘<’;

③加在一個‘<’的中間:

實際上不會增長‘<’,所以不會對答案產生影響qwq;

④加在一個‘>’中間:

增長了一隻‘<’。

因此由此咱們能夠推出狀態轉移方程:

當i加在第①③種狀況時,不會產生新的‘<’,所以咱們須要由dp[i-1][j]推過來。

能夠計算1~i-1的序列中,共有j個‘<’號,而後還有①狀況中的一種,共有j+1種狀況是添加後不增長‘<’的,因此dp[i][j]+=dp[i-1][j]*(j+1);

當i加在第②④種狀況時,會產生新的'<',所以咱們也須要由dp[i-1][j-1]推得:

④狀況:咱們知道當前狀況下1~i-1中共有j-1個‘>’,總共的符號數爲i-2個,所以其中‘>’數爲i-2-(j-1)=i-j-1個,再加上②狀況的一種,因此共有i-j個能夠產生一個新的‘<’;所以dp[i][j]+=dp[i-1][j-1]*(i-j);

轉移方程:dp[i][j]=dp[i-1][j]*(j+1)+dp[i-1][j-1]*(i-j);//注意取模

而後是初始狀態:

當咱們有0個‘<’時,不管有幾個數,這些數必須嚴格升序排列,也就是隻有一種排列是知足有0個‘<’的;所以初始化:dp[1~n][0]=1;

最後的答案顯然就是dp[n][k]了;

CODE:

#include<bits/stdc++.h>

using namespace std;

int n,k;
int dp[1010][1010];

int main(){
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++) dp[i][0]=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=k;j++){
            dp[i][j]=(dp[i-1][j]*(j+1)%2015+dp[i-1][j-1]*(i-j)%2015)%2015;
        }
    }
    printf("%d",dp[n][k]);
    return 0;
}

end- 

相關文章
相關標籤/搜索