题解:太空信号
题目描述
FJ农场的射电望远镜收到了来自外太空的神秘信号,奶牛贝蒂将其解码后得到如一个数列:
\(1\) \(3\) \(0\) \(2\) \(-1\) \(1\) \(-2\) ...
贝蒂发现这个数列是有规律的,数列中后一项总是比前一项增加2或者减少3,贝蒂将这种后一项总是比前一项增加\(a\)或者减少\(b\)的数列命名为BD数列。
贝蒂想知道对于一个给定长度为\(n\),数列总和为\(s\),并且后一项总是比前一项增加\(a\)或者减少\(b\)的BD数列有多少种。
输入格式
输入的第一行包含四个整数 \(n\) \(s\) \(a\) \(b\),含义如前面说述。
输出格式
输出一行,包含一个整数,表示满足条件的方案数。由于这个数很大,请输出方案数除以\(1000000007\)的余数。
输入输出样例
输入样例 1
4 10 2 3
输出样例 1
2
输入样例 2
15 38 3 1
输出样例 2
1091
提示
样例1说明
这两个数列分别是\(2\) \(4\) \(1\) \(3\)和\(7\) \(4\) \(1\) \(-2\)。
数据规模和约定
对于10%的数据,\(1 \leq n \leq 5\),\(0 \leq s \leq 5\),\(1 \leq a,b \leq 5\);
对于30%的数据,\(1 \leq n \leq 30\),\(0 \leq s \leq 30\),\(1 \leq a,b \leq 30\);
对于50%的数据,\(1 \leq n \leq 50\),\(0 \leq s \leq 50\),\(1 \leq a,b \leq 50\);
对于70%的数据,\(1 \leq n \leq 100\),\(0 \leq s \leq 500\),\(1 \leq a, b \leq 50\);
对于100%的数据,\(1 \leq n \leq 1000\),\(-1,000,000,000 \leq s \leq 1,000,000,000\),\(1 \leq a, b \leq 1,000,000\)。
思路
每个操作都是 +a -b 或 -a+b ,我们很容易可以想到使用dp,具体看代码
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MOD = 100000007;
signed main() {
int n, s, a, b;
cin >> n >> s >> a >> b;
long long f[1000000] = {0};
f[0] = 1;
for (int i = 1; i < n; i++) {
for (int j = i * (i + 1) / 2; j >= i; j--) {
f[j] = (f[j] + f[j - i]) % MOD;
}
}
long long cnt = 0, t;
for (int i = 0; i <= n * (n - 1) / 2; i++) {
t = s - i * a + (n * (n - 1) / 2 - i) * b;
if (t % n == 0) {
cnt = (cnt + f[i]) % MOD;
}
}
printf("%lld", cnt);
return 0;
}

浙公网安备 33010602011771号