波动数列

波动数列

观察这个数列:

1 3 0 2 1 1 2

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

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

输入格式

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

输出格式

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

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

数据范围

1n1000,
109s109,
1a,b106

输入样例:

4 10 2 3

输出样例:

2

样例解释

两个满足条件的数列分别是2 4 1 37 4 1 2

 

解题思路

  我们发现上面求和的等式有很多的变量,其中xZ有无穷多种选法,每个di都有两种选法。因此每一个不同的x和每一组不同的di都对应一种不同的方案。

  我们可以发现这是一个等式,意味着可以去掉一个变量,即可以用其中的n1个变量去表示某一个变量(一个很重要的思想,我经常想不到)。由于x可以取到很多值,所以我们可以用di来表示x

  因此x可以表示为x=s((n1)d1+(n2)d2+......+dn1)n也就是说,当我们的di都确定后,x也是唯一确定的,是可以求出来的。

  因此任何一个合法的序列都对应一组di的取值,任何一组di的取值都可以对应一个原来的序列,因此这是一一对应的关系。因此原序列所有不同的方案数就等于所有di的合法取值的方案数。

  因此等价于求所有满足要求的di的取值的方案数。满足的要求有:di只有两种取值方式;由于x为整数,所以s((n1)d1+(n2)d2+......+dn1)应该为n的倍数。等价于要满足s((n1)d1+(n2)d2+......+dn1)0 (mod n)(n1)d1+(n2)d2+......+dn1s (mod n)

  所以我们可以发现这是一个组合的问题,要求我们找到di的一个组合,满足(n1)d1+(n2)d2+......+dn1s (mod n),类似于一个背包问题。

  其中我们原本的式子为(n1)d1+(n2)d2+......+dn1,我们可以变为d1+2d2+......+(n1)dn1,因为每个di是等同的,每个di都是取+ab,因此改变变量名称是不影响的。其实不进行变换也是可以的,变化后处理会方便点。

  在状态计数中,最后一项是+a的所有方案这个集合中,对于前i1项有c+iaj (mod n),因此有cj(ia) (mod n)。同理可得到对于最后一项是b的所有方案这个集合中,有cj+ib (mod n)。都可以从f(i1,c)状态转移到f(i,j)

  AC代码如下:

复制代码
 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int N = 1010, mod = 100000007;
 6 
 7 int f[N][N];
 8 
 9 int main() {
10     int n, s, a, b;
11     scanf("%d %d %d %d", &n, &s, &a, &b);
12     
13     f[0][0] = 1;    // 初始化:一项都不选,总和是0的情况
14     for (int i = 1; i < n; i++) {
15         for (int j = 0; j < n; j++) {
16             f[i][j] = (f[i - 1][((j - i * a) % n + n) % n] + f[i - 1][(j + i * b) % n]) % mod;
17         }
18     }
19     
20     printf("%d", f[n - 1][(s % n + n) % n]);
21     
22     return 0;
23 }
复制代码

 

参考资料

  AcWing 1214. 波动数列(蓝桥杯C++ AB组辅导课):https://www.acwing.com/video/639/

posted @   onlyblues  阅读(191)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
Web Analytics
点击右上角即可分享
微信分享提示