题目描述:
![](https://img-blog.csdnimg.cn/img_convert/192e7c05460e3459a695a770cc6d726c.png)
解题思路:
首先我们先看下怎么对题目
进行问题的转换
题目问题转换:
![](https://img-blog.csdnimg.cn/img_convert/c2b16f1287d3f963821c8b13388ac4a2.jpeg)
动态规划分析:
对于f[i][j]我们就可以得到
他是 f[i-1][(j-a*(n-i))%n] 与 f[i-1][j+b*(n-i)%n] 的和
从而不断推出每个方案的合法方案数
类似01背包
![](https://img-blog.csdnimg.cn/img_convert/554f48a285841f3da511690abd84d6bc.png)
代码详细:
#include<iostream>
using namespace std;
typedef long long ll;
const int Mo=100000007;
const int N=1e3+6;
ll f[N][N];
ll n,s,a,b;
ll get_mod(ll x,ll y){
return (x%y+y)%y;
}//对数取模,保证取模后为正。
int main(){
cin>>n>>s>>a>>b;
s%=n,a%=n,b%=n;
f[0][0]=1;//初始化
for(int i=1;i<n;i++){//i表示第几个,j表示余数是多少
for(int j=0;j<n;j++){
f[i][j]=(f[i-1][get_mod(j-a*(n-i),n)]+f[i-1][get_mod(j+b*(n-i),n)])%Mo;
}
}
cout<<f[n-1][get_mod(s,n)];
}
注:
对于j-a*(n-i)等等数值可能是一个负数,对于负数在计算机的计算机中取模后仍然为负数,所以我们要对它进行处理,让它取模后大于0,所以就用到了上面的 get_mod()函数
例如:
计算机中计算:
![](https://img-blog.csdnimg.cn/img_convert/3068d8cd09122ff3dd4dad2a5836bba5.png)
实际计算:
![](https://img-blog.csdnimg.cn/img_convert/25fb446cacc318444f584df1299dace9.png)