蓝桥杯历届真题 波动数列

发布时间 2023-03-26 19:19:52作者: Liang2003

波动数列

题意

一个数列有以下性质:\(c_i=c_{i-1}+a或者c_i=c_{i-1}-b,i\in[2,n]\).
求一个长度为n,总和为s的数列有多少个。

思路

显然 在位置\(pos\in[2,n]\),假设\(c_{pos}=c_{pos-1}+x\),则这个值x对整个数组的贡献为\((n-pos+1)*x\),对于所有的值x,有 \(s-t =ny\),t为所有x的贡献,s-t是n的倍数,这就是本题最重要的点,s和t在模n下同余,之后就是简单的dp了

代码

void solve()
{
	cin>>n>>m>>a>>b;
    m%=n;
    m=(m+n)%n;
    a%=n,b%=n;
    f[0][0]=1;
    for(int i=1;i<n;i++) 
    {
    	for(int j=0;j<n;j++) 
    	{
    		f[i][j]=(f[i][j]+f[i-1][(j+((n-i)*b%n)+n)%n])%mod;
    		f[i][j]=(f[i][j]+f[i-1][(j-((n-i)*a%n)+n)%n])%mod;
    	}
    }
    cout<<f[n-1][m]%mod<<endl;
}