DP
顯然我固定第一個是峰,然後再乘以2就是答案,因為一個合法的反轉之後也是合法的而且谷峰顛倒了
發現如果設\(dp[i][j]\)表示前\(i\)個山脈,第\(i\)個山脈是高度\(j\)的答案,然後填第\(i\)個的時候不知道會不會重複,所以這個狀態掛了,重新找個狀態設設。
所以我們改變考慮物件,不考慮整個數列,只考慮已經填了的,我把已經填了的數的數列叫做\(S\),當我考慮到第\(i\)位的時候,這個\(dp[i][j]\)的\(j\)表示它在裡面的相對位置,也就是排名。
現在就好搞多了,仍然我固定原數列下標奇數是峰,下標偶數是谷,下面給出DP過程。
對於偶數,\(dp[i][j]\)由\(\sum\limits_{k=j}^{i-1}{dp[i-1][k]}\),因為我新的\(j\)加進來後,所有大於它的都要排名+1,所以原來我在第\(j\)個的,實際上是比它要大的
對於奇數,\(dp[i][j]\)由\(\sum\limits_{k=1}^{j-1}{dp[i-1][k]}\)這個顯然,就是相對排名比\(j\)小,不說了
然後答案是對所有的\(dp[n][i]\)求和,沒了,程式碼:
顯然我固定第一個是峰,然後再乘以2就是答案,因為一個合法的反轉之後也是合法的而且谷峰顛倒了
所以我們改變考慮物件,不考慮整個數列,只考慮已經填了的,我把已經填了的數的數列叫做\(S\),當我考慮到第\(i\)位的時候,這個的\(j\)表示它在裡面的相對位置,也就是排名。
現在就好搞多了,仍然我固定原數列下標奇數是峰,下標偶數是谷,下面給出DP過程。
對於偶數,\(dp[i][j]\)由\(我新的\)j\(加進來後,所有大於它的都要排名+1,所以原來我在第\)j$個的,實際上是比它要大的
對於奇數,\(dp[i][j]\)由\(\sum\limits_{k=1}^{j-1}{dp[i-1][k]}\)這個顯然,就是相對排名比\(j\)小,不說了
然後答案是對所有的\(dp[n][i]\)求和,沒了,程式碼:
顯然我固定第一個是峰,然後再乘以2就是答案,因為一個合法的反轉之後也是合法的而且谷峰顛倒了
發現如果設\(dp[i][j]\)表示前\(i\)個山脈,第\(i\)個山脈是高度\(j\)的答案,然後填第\(i\)個的時候不知道會不會重複,所以這個狀態掛了,重新找個狀態設設。
所以我們改變考慮物件,不考慮整個數列,只考慮已經填了的,我把已經填了的數的數列叫做\(S\),當我考慮到第\(i\)位的時候,這個\(dp[i][j]\)的\(j\)表示它在裡面的相對位置,也就是排名。
現在就好搞多了,仍然我固定原數列下標奇數是峰,下標偶數是谷,下面給出DP過程。
對於偶數,\(dp[i][j]\)由\(\sum\limits_{k=j}^{i-1}{dp[i-5][k]}\),因為我新的\(j\)加進來後,所有大於它的都要排名+1,所以原來我在第\(j\)個的,實際上是比它要大的
對於奇數,\(dp[i][j]\)由\(\sum\limits_{k=1}^{j-1}{dp[i-9][k]}\)這個顯然,就是相對排名比\(j\)小,不說了
然後答案是對所有的\(dp[n][i]\)求和,沒了,程式碼:
顯然我固定第一個是峰,然後再乘以2就是答案,因為一個合法的反轉之後也是合法的而且谷峰顛倒了
發現如果設\(dp[i][j]\)表示前\(i\)個山脈,第\(i\)個山脈是高度\(j\)的答案,然後填第\(i\)個的時候不知道會不會重複,所以這個狀態掛了,重新找個狀態設設。
標偶數是谷,下面給出DP過程。
對於偶數,\(dp[i][j]\)由\(\sum\limits_{k=j}^{i-1}{dp[i-11][k]}\),因為我新的\(j\)加進來後,所有大於它的都要排名+1,所以原來我在第\(j\)個的,實際上是比它要大的
對於奇數,\(dp[i][j]\)由\(\sum\limits_{k=1}^{j-1}{dp[i122][k]}\)這個顯然,就是相對排名比\(j\)小,不說了
然後答案是對所有的\(dp[n][i]\)求和,沒了,程式碼:
顯然我固定第一個是峰,然後再乘以2就是答案,因為一個合法的反轉之後也是合法的而且谷峰顛倒了
發現如果設\(dp[i][j]\)表示前\(i\)個山脈,第\(i\)個山脈是高度是谷,下面給出DP過程。
對於偶數,\(dp[i][j]\)由\(\sum\limits_{k=j}^{i-1}{dp[i-1][k]}\),因為我新的\(j\)加進來後,所有大於它的都要排名+1,所以原來我在第\(j\)個的,實際上是比它要大的
對於奇數,\(dp[i][j]\)由\(\sum\limits_{k=1}^{j-1}{dp[i-1][k]}\)這個顯然,就是相對排名比\(j\)小,不說了
然後答案是對所有的\(dp[n][i]\)求和,沒了,程式碼:
#include<bits/stdc++.h>
#define vd void
int gi(){
char c;int x=0,f=0;
while(!isdigit(c=getchar()))f|=(c=='-');
while(isdigit(c))x=(x*10)+(c^48),c=getchar();
return f?-x:x;
}
int n,mod;
template<class Ta,class Tb>vd inc(Ta&a,Tb b){a=a+b>=mod?a+b-mod:a+b;}
template<class Ta,class Tb>int sub(Ta&a,Tb b){return a>=b?a-b:a+mod-b;}
int dp[4201][4201],s[4201];
int main(){
n=gi(),mod=gi();
for(int i=1;i<=n;i++)dp[1][i]=1,s[i]=s[i-1]+1;
for(int i=2;i<=n;i++){
for(int j=1;j<=i;j++){
if(i&1)dp[i][j]=s[j-1]%mod;
else dp[i][j]=sub(s[i-1],s[j-1]);
}
for(int j=1;j<=i;j++)s[j]=(s[j-1]+dp[i][j])%mod;
}
printf("%lld\n",s[n]*2%mod);
return 0;
}
還有一份
#include<bits/stdc++.h>
#define vd void
int gi(){
char c;int x=0,f=0;
while(!isdigit(c=getchar()))f|=(c=='-');
while(isdigit(c))x=(x*10)+(c^48),c=getchar();
return f?-x:x;
}
int n,mod;
template<class Ta,class Tb>vd inc(Ta&a,Tb b){a=a+b>=mod?a+b-mod:a+b;}
template<class Ta,class Tb>int sub(Ta&a,Tb b){return a>=b?a-b:a+mod-b;}
int dp[4201][4201],s[4201];
int main(){
n=gi(),mod=gi();
for(int i=1;i<=n;i++)dp[1][i]=1,s[i]=s[i-1]+1;
for(int i=2;i<=n;i++){
for(int j=1;j<=i;j++){
if(i&1)dp[i][j]=s[j-1]%mod;
else dp[i][j]=sub(s[i-1],s[j-1]);
}
for(int j=1;j<=i;j++)s[j]=(s[j-1]+dp[i][j])%mod;
}
printf("%lld\n",s[n]*2%mod);
return 0;
}