其他分享
首页 > 其他分享> > 洛谷 P2467 [SDOI2010]地精部落(dp)

洛谷 P2467 [SDOI2010]地精部落(dp)

作者:互联网

传送门


解题思路

设dp[i][j]表示用前i个数,第一段山脉的高度为j,且j为山峰的方案数。
首先发现,dp[i][j]=dp[i][i-j+1],相当于把每个数取了个相反数,原来的山峰变山谷,山谷变山峰,方案数不变。
然后状态转移:

最后答案就是

\[ans=2\times\sum_{j=1}^{n}dp[n][j] \]

为什么要 \(\times2\) 呢?因为sum只统计了第一个山作为山峰的方案数,而山谷的方案数与其相等。
再加上滚动数组优化一下即可。

AC代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<algorithm>
using namespace std;
int n,p,dp[2][4205];
long long ans;
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>p;
	dp[1][1]=1;
	for(int i=2;i<=n;i++){
		for(int j=1;j<=i;j++){
			dp[i&1][j]=(dp[i&1][j-1]+dp[(i-1)&1][(i-1)-(j-1)+1])%p;
		}
	}
	for(int i=1;i<=n;i++) ans+=dp[n&1][i];
	cout<<ans*2%p;
    return 0;
}

标签:山峰,洛谷,山谷,方案,int,SDOI2010,P2467,include,dp
来源: https://www.cnblogs.com/yinyuqin/p/15254207.html