先不废话,ac代码
include[HTML_REMOVED]
using namespace std;
int samemod(int a,int b)
{
return (a % b + b) % b;
}
int main()
{
int n, s, a, b;
cin >> n >> s >> a >> b;
int dp[1001][1001];
dp[0][0] = 1;
for (int i = 1; i < n; i)
{
for (int j = 0; j < n; j)
{
dp[i][j] = (dp[i - 1][samemod(j-a(n-i), n)] + dp[i - 1][samemod(j+b(n-i),n)]) % 100000007;
}
}
cout << dp[n - 1][samemod(n, s)];
return 0;
}
详细解析
首先设首相x,项数n,每项变化量为d,d1等(因为可以是a或者b两种值,所以不能化简),可得式子s=x+(x+d)+(x+d+d1)......(x+d+d1…+dn-1),化简得s=nx+(n-1)d…+dn-1,由于x和n是整数,所以(s-(n-1)d....-dn-1)%n=x,此时要给出一个公式(记忆即可):(a+b)%c=a%c=b%c,且a%c=-a%c所以,s%n与((n-1)d+....dn-1)%n的值是相同的
所以可以套一下同余公式(记忆即可)(a%b+b)%b的值是同余两个值的余数
所以来看题目的动态规划部分,首先要求的是方法总数,且是数组背景,所以一定是二维数组且第一维要随着数组进行遍历,第二晚是选择位,分为选择a和选择b两种,现在来看选择a和b有什么影响,观察上面给出的式子,选a总和就增加了a(n-i),选b总和就减少了b(n-i),这一点可以通过数项数进行验证,第二维选择余数,因为我们上面的分析是围绕余数展开的,dp[i][j]是数列推进到i时余数为j的情况,由于是余数,所以范围是0到n-1,因为到n就可以整除了再用同余定理求余数即可