波动数列——蓝桥杯真题

波动数列

题目描述:观察这个数列:

1 3 0 2 -1 1 -2 …

这个数列中后一项总是比前一项增加2或者减少3,且每一项都为整数

栋栋对这种数列很好奇,他想知道长度为 n和为 s而且后一项总是比前一项增加 a或者减少 b的整数数列可能有多少种呢?

输入格式

共一行,包含四个整数 n,s,a,b,含义如前面所述。

输出格式

共一行,包含一个整数,表示满足条件的方案数。

由于这个数很大,请输出方案数除以 100000007 的余数。

数据范围

1≤n≤1000 −10^9≤s≤10^9 1≤a,b≤10^6

输入样例:

 4 10 2 3

输出样例:

 2

样例解释

两个满足条件的数列分别是2 4 1 3和7 4 1 -2。

 

分析图:

code:

 #include<cstdio>
 #include<cstring>
 #include<iostream>
 #include<algorithm>
 using namespace std;
 int n,s,a,b;
 const int N = 1010,MOD = 1e8 + 7;
 int f[N][N];
 
 int get_mod(int x,int y){
  //鉴于余数可能为负,所以加上y再模y即可
  return (x%y+y)%y;
 }
 int main(){
  cin>>n>>s>>a>>b;
 
  f[0][0] = 1;//初始化,前0项部分和模n为0的解为1.
  for(int i=1;i<=n;i++){
  for(int j=0;j<n;j++){//逐一枚举n的余数(0~n-1).
  f[i][j] = (f[i-1][get_mod(j - (n-i)*a,n)] + f[i-1][get_mod(j + (n-i)*b,n)]) % MOD;
  }
  }
 
  //因为数列有n项,所以部分和就有n-1项,且这前n-1项部分和与s模n同余--详见上图推导^_^
  cout<<f[n-1][get_mod(s,n)]<<endl;
  return 0;
 }

 

原文地址:https://www.cnblogs.com/yuanshixiao/p/14507203.html