A - 地精部落 (DP)
题目链接:https://cn.vjudge.net/contest/281960#problem/A
题目大意:中文题目。
具体思路:首先,如果有一段是山谷的话,那么这一段中也能用来表示山峰,只要将每一个的高度用N减一下,这样就形成了一个山峰。我们通过一个二维数组,dp[i][j]代表长度为i,第一位高度在[1,j]的满足山峰的方案数,我们就可以求出另一个表达式dp[i][j]=dp[i][j-1]+dp[i-1][j-1].(注意第一个i和第二个i不相同)这个怎么理解呢?首先dp[i-1][j]这个比较好理解,就是把原来长度已经存在的是山峰的加上,另外,我们需要把原来长度是i-1,首位是j-1并且是山谷的方案数求出来=dp[i-1][i-j+1](山谷和山峰是相对的)=dp[i][i-j].
dp[i][j]=dp[i][j-1]+f[i-1][j-1]=dp[i][j-1]+dp[i-1][i-1-(j-1)+1]=dp[i][j-1]+dp[i-1][i-j+1].
AC代码:
1 #include<iostream> 2 #include<stdio.h> 3 #include<stack> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 # define ll long long 8 const int maxn = 1e5+100; 9 ll a[3][maxn]; 10 int main() 11 { 12 int n,m; 13 scanf("%d %d",&n,&m); 14 a[1][1]=1; 15 int tmp=1; 16 for(int i=2; i<=n; i++) 17 { 18 tmp^=1; 19 for(int j=1; j<=i; j++) 20 { 21 a[tmp][j]=(a[tmp][j-1]+a[tmp^1][i-j])%m; 22 } 23 } 24 printf("%lld\n",(a[tmp][n]*2)%m); 25 return 0; 26 }