波动数列

  观察这个数列:
    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。

题意:输入四个数n,s,a,b;

n:表示输出结果为n个数

S:表示n个数的和要为s

a:表示每次增加a

b:表示每次减少b

首先我们要知道这个数列的范围,最小值和最大值,假如n个数一直递减,每次减b,就是n*b,而我们题目要求的总和为s,所以最小值从s-n*b开始就可以了,同理最大值为s+n*a

然后从写一个递归函数把最小值到最大值依次传入,在函数里面做加a减b的操作,最后的和为题目要求的就记录下来

import java.util.Scanner;


public class Main {
	static int n, s, a, b;


	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		while (cin.hasNext()) {
			n = cin.nextInt();
			s = cin.nextInt();
			a = cin.nextInt();// 增加的数
			b = cin.nextInt();// 减少的数
			for (int i = s - n * b; i <= s + n * a; i++) {
				find(1, i + " ", i, i);
			}
			System.out.println(id%100000007);
			id=0;
		}
		cin.close();
	}
	static int id=0;
	public static void find(int d, String str, int ss, int sum) {//d用来记录个数,str保存结果,ss当前的数,sum所有数的总和
		if (d == n && sum == s) {// 个数达到时
			id++;
			System.out.println(str);
		} else if (d > n) {//个数超过时返回
			return;
		} else {
			int s1 = ss + a;//增加a后的数
			find(d + 1, str + s1 + " ", s1, sum + s1);
			int s2 = ss - b;//减少b后的数
			find(d + 1, str + s2 + " ", s2, sum + s2);
			
		}
	}


}


	
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原飞木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值