问题描述 观察这个数列: 1 3 0 2 -1 1 -2 …
这个数列中后一项总是比前一项增加2或者减少3。
栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢? 输入格式
输入的第一行包含四个整数 n s a b,含义如前面说述。 输出格式
输出一行,包含一个整数,表示满足条件的方案数。由于这个数很大,请输出方案数除以100000007的余数。 样例输入 4 10 2 3
样例输出 2 样例说明 这两个数列分别是2 4 1 3和7 4 1 -2。 数据规模和约定
对于10%的数据,1<=n<=5,0<=s<=5,1<=a,b<=5;
对于30%的数据,1<=n<=30,0<=s<=30,1<=a,b<=30;
对于50%的数据,1<=n<=50,0<=s<=50,1<=a,b<=50;
对于70%的数据,1<=n<=100,0<=s<=500,1<=a, b<=50;
对于100%的数据,1<=n<=1000,-1,000,000,000<=s<=1,000,000,000,1<=a,
b<=1,000,000。 ————————————————
先用一把深搜解决,并不能实际解决问题
import java.util.Scanner;
/**
* @Author susuper
* @Date 2019/11/19 17:13
* @description:
*/
public class bodong1119 {
static int n,s,a,b,num;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
s = sc.nextInt();
a = sc.nextInt();
b = sc.nextInt();
int maxV = s + n*b; //可以递增的最多值
for(int i = s-n*a;i<=maxV;i++ ){
dfs(i,i,1);
}
System.out.println(num);
}
public static void dfs(int cur,int all,int len){ // 当前值 总大小 长度
if(len==n){
if(all == s){
num++;
num%=100000007;
return;
}
else{
return;
}
}
dfs(cur+a,all+cur+a,len+1); //下一个值要+a
dfs(cur-b,all+cur-b,len+1); //下一个值要-b
}
}
使用dp,几乎不会~~
import java.util.Scanner;
/**
* @Author susuper
* @Date 2019/11/19 17:13
* @description:
* 参考了很多博客,看懂了这道题目,可以用dfs解,但是必然会无法满足一些要求,用dp转化为01背包问题解决
* 刚开始学动态规划,写起来还是比较困难的,最近几天要恶补一下动态规划了qaq
*/
public class bodong1119 {
final static int maxn = 1100;
static int n,s,a,b,num;
static int p = 0;
static long dp[][] = new long[2][maxn*maxn];
static long count = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
s = sc.nextInt();
a = sc.nextInt();
b = sc.nextInt();
num = n*(n-1)/2; //计算有多少个+3或-2
dp();
sum();
System.out.println(count);
}
public static void dp(){
int i,j;
dp[p][0] = 1; //最开始的时候,只有一个体积为0的物品,可以放到容量为0的背包,背包方案数是0
for(i =1;i<n;i++){
p = 1-p;
for( j = 0;j<=(i+1)*i/2;j++){
if(i>j){ //当前背包放不下 比前一个大一个的物品 所以放前一个
dp[p][j] = dp[1-p][j];
}else{
dp[p][j] = (dp[1-p][j] + dp[1-p][j-i]) % 100000007;
}
}
}
}
public static void sum(){
for(int i = 0;i<=num;i++){
int temp = s - i*a+(num-i)*b;
if(temp%n==0){
count = (count+dp[p][i])%100000007;
}
}
}
}