一、题目链接
二、题目分析
(一)算法标签
动态规划
(二)解题思路
1.状态表示
[ ( n − 1 ) d 1 + ( n − 2 ) d 2 + . . . + ( n − i ) d i ] ≡ s ( m o d n ) [(n - 1)d~1~ + (n - 2)d~2~ + ... + (n - i)d~i~]≡s(mod n) [(n−1)d 1 +(n−2)d 2 +...+(n−i)d i ]≡s(modn)
集合:
f[i][j]
表示所有前i
个数(下标从0 ~ n)的数列, 模n
后余数为j
的方案的集合
属性:
数量
2.状态计算(集合划分)
-
选
a
:f[i - 1][(j - (n - 1) * a) % n]
-
选
-b
:f[i - 1][(j + (n - 1) * b) % n]
初始化:
f[0][0] = 1
三、AC代码
解法一:
#include<iostream>
using namespace std;
const int N = 1010, MOD = 100000007;
int n, s, a, b;
// f[i][j] 表示0 ~ i项, 余数为j的方案数
int f[N][N]; // 因为最后要模n所以余数为0 ~ n - 1
int getmod(int a, int b)
{
return (a % b + b) % b; // 得到a % b 的正余数
}
int main()
{
cin >> n >> s >> a >> b;
// 初始化
f[0][0] = 1;
for (int i = 1; i < n; i ++ )
for (int j = 0; j < n; j ++ )
{
f[i][j] = (f[i - 1][getmod(j - (n - i) * a, n)] + f[i - 1][getmod(j + (n - i) * b, n)]) % MOD;
}
cout << f[n - 1][getmod(s, n)];
return 0;
}