[SDOI2010][BZOJ 1925]地精部落
Posted PaperCloud
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SDOI2010][BZOJ 1925]地精部落相关的知识,希望对你有一定的参考价值。
Description
Input
Output
#include<bits/stdc++.h> using namespace std; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();} return x*f; } int n,mod; int f[4205][2][4205],ans; int main(){ n=read(),mod=read(); f[2][1][2]=f[2][0][1]=1; f[3][0][1]=f[3][0][2]=f[3][1][2]=f[3][1][3]=1; register int i,j,k; for(i=4;i<=n;i++) for(j=1;j<=i;j++){ for(k=1;k<j;k++) f[i][1][j]=(f[i][1][j]+f[i-1][0][k])%mod; for(k=j;k<i;k++) f[i][0][j]=(f[i][0][j]+f[i-1][1][k])%mod; } for(i=1;i<=n;i++) ans=(ans+f[n][0][i]+f[n][1][i])%mod; printf("%d\n",ans); return 0; }
正解不是很难理解,首先,三个性质了解一下:
First : 对于每一个 数字 i 和 i+1 , 如果这两个数不是相邻的,那么交换两个数字的对应的方案数是一样的! 比如有 波动序列 3241532415 和 1243512435
Second: 我们由 1~n 的波动数列的任意一种,将每一个 ai? 都可以用(n+1) 减去,那么得到的新的序列其实还是合法的,而且相对的山谷和山峰会改变!
比如有 波动序列 3241532415 和 3425134251
Third : 波动数列具有对称性......(那不是废话)
DP[i][j]表示 选 1 To i 这些数字,第一个数为山峰,且第一个数为 j;答案就是 ∑ DP[N][j] (j = 1 to N)
DP[i][j]=DP[i][j-1]+DP[i-1][i-j+1]
证明:由性质一可知,当j与j-1不相邻的时候,j作为头所有的方案数与j-1作为头的方案数相同,于是就有DP[I][J]=DP[I][J-1];
对于DP[i][j]+=DP[i-1][i+j-1];就是当j 与 j-1相邻时的情况;
我们可以这么想,我第一个数选择了J 并且定义为山峰,那我第二个数j-1必定为山谷,后面的数属于[1,j-1]和[j+1,i];
此时问题转化成了求 i-1个数,j-1为头,但是j-1 为山谷的方案数,由性质2可知,j-1作山谷和作山峰的方案数相同;
现在的问题就是,此时的区间和我DP方程的区间意义不同;
没关系;因为山峰与山谷是相对位置关系,将[j+1,i]区间的每个数都减一,这样是不改变相对大小关系的,并且此时就符合我们的方程了;
另外,我DP[i-1][j-1]表示的是J-1为山顶时的个数,为了让其表示J-1为山谷的情况,要改成DP[i-1][(i-1+1)-(j-1)];
这样就得到了我们的转移方程,我们可以用滚动数组优化空间;
代码:
#include<bits/stdc++.h> using namespace std; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();} return x*f; } int f[2][4205]; int n,mod,ans; int main(){ n=read(),mod=read(); f[0][2]=1; for(int i=3;i<=n;i++)for(int j=2;j<=i;j++) f[i&1][j]=(f[i&1][j-1]+f[(i-1)&1][i-j+1])%mod; ans=0; for(int j=2;j<=n;j++)ans=(ans+f[n&1][j])%mod; printf("%d",(ans<<1)%mod); return 0; }
来自PaperCloud的博客,未经允许,请勿转载,TKS!
以上是关于[SDOI2010][BZOJ 1925]地精部落的主要内容,如果未能解决你的问题,请参考以下文章