蓝桥杯:波动数列

问题描述

  观察这个数列:

  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。

Thinking:

设:有数组a[n],首项为a[0]

依题意有:a[0]+a[1]+....a[n]=s;

易知,a[0]的下限为:

a[0]+(a[0]+a)+(a[0]+2*a)+....+(a[0]+(n-1)*a)=s

<==> n*a[0]+(n*(n-1)/2)*a=s;

<==> a[0]=(s-(n*(n-1)/2)*a)/n; 此时得到a[0]的下限.

a[0]的最大值为

a[0]+(a[0]-b)+(a[0]-2*b)+....+(a[0]+(n-1)*b)=s

<==>n*a[0]-(n*(n-1)/2)*b=s;

<==>a[0]=(s+(n*(n-1)/2)*b)/n;
此时得到a[0]的上限.

综上得到首项a[0]的范围:

(s-(n*(n-1)/2)*a)/n
<= a[0] <= (s+(n*(n-1)/2)*b)/n

设items=n*(n-1)/2,x为a的个数,y为b的个数,items是a的个数加上b的个数的和,则有:

x+y==items

这样写完之后发现结果不通过,思考之后发现,很有可能是x个a,和y个b的排列顺序不一致,导致得到的结果少了,

所以之后加了一个判断函数more();

再去提交,结果对了,有部分超时,80%的数据出错,我就想,是不是int overRange了,所以把所有的int换成了longlong(其实没必要把所有的都换),之后所有数据都通过了,但是超时.如果把dfs()部分,换成dp,应该快很多,先这样.

#include<iostream>
#define module 100000007
using namespace std;
long long  tempCount;
void dfs(long long  step,long long  a,long long  b,long long  temp,long long  sum,long long  s,long long  n)
{
	if(step>=n)
		return;
	else if(step==n-1)
	{
		if(sum==s)
			tempCount++;
		return;
	}

	temp+=a;
	dfs(step+1,a,b,temp,sum+temp,s,n);
	temp-=a;

	temp-=b;
	dfs(step+1,a,b,temp,sum+temp,s,n);
	temp+=b;
}
long long  more(long long  a1,long long  a,long long  b,long long  x,long long  y,long long  n,long long  s)
{
	tempCount=0;
	dfs(0,a,b,a1,a1,s,n);
	return tempCount;
}
int  main()
{
	long long  n,s,a,b,a1,i,k,lowLimit,highLimit,items,counter=0;
	cin>>n>>s>>a>>b;
	items=n*(n-1)/2;
	lowLimit=(s-items*a)/n;
	highLimit=(s+items*b)/n;

	for(a1=lowLimit;a1<=highLimit;a1++)
		for(i=0;i<=items;i++)
			if(n*a1+i*a-(items-i)*b==s)
			{
					counter+=more(a1,a,b,i,items-i,n,s);
					if(counter>module)
						counter%=module;
			}
	cout<<counter<<endl;
	return 0;
}
时间: 2024-08-05 10:50:45

蓝桥杯:波动数列的相关文章

蓝桥杯 波动数列 【未完成】

历届试题 波动数列 时间限制:1.0s   内存限制:256.0MB 问题描述 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个数列中后一项总是比前一项增加2或者减少3. 栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢? 输入格式 输入的第一行包含四个整数 n s a b,含义如前面说述. 输出格式 输出一行,包含一个整数,表示满足条件的方案数.由于这个数很大,请输出方案数除以100000007的余数. 样例输入 4

蓝桥杯 波动数列 01背包

借鉴自:https://blog.csdn.net/wr132/article/details/43861145 https://blog.csdn.net/linqing360/article/details/79653002 题目大意: 问题描述 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个数列中后一项总是比前一项增加2或者减少3. 栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢? 输入格式 输入的第一行包含

蓝桥杯 BASIC-13 数列排序

[思路]:排序.可以用 sort 或者 qsort ,或者常见的冒泡. [AC代码]: 常规: #include <iostream> #include <algorithm> using namespace std; #define MAX 200+10 int main() { int i = 0, n = 0; int num[MAX]; cin >> n; for (i = 0; i < n; i++) cin >> num[i]; sort(

蓝桥杯评测_fibonacci数列问题

最近在做蓝桥杯评测题,发现通过这个评测确实可以提高自己的写代码的规范,也增长了自己的知识. 问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式 输入包含一个整数n. 输出格式 输出一行,包含一个整数,表示Fn除以10007的余数. 说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以100

蓝桥杯 入门训练 Fibonacci数列(Java)

@Author : qingdujun 入门训练 Fibonacci数列  : http://lx.lanqiao.org/problem.page?gpid=T4 import java.util.Scanner; /** * 蓝桥杯: 入门训练 Fibonacci数列 * @author qingdujun * */ public class Main { public static void main(String[] args) { int f1 = 1; int f2 = 1; int

蓝桥杯历届-奇怪的数列

蓝桥杯历届-奇怪的数列 还不复习算法,估计国赛会跪... 标题:奇怪的数列 从X星截获一份电码,是一些数字,如下: 13 1113 3113 132113 1113122113 .... YY博士经彻夜研究,发现了规律: 第一行的数字随便是什么,以后每一行都是对上一行"读出来" 比如第2行,是对第1行的描述,意思是:1个1,1个3,所以是:1113 第3行,意思是:3个1,1个3,所以是:3113 请你编写一个程序,可以从初始数字开始,连续进行这样的变换. 数据格式: 第一行输入一个数

蓝桥杯-入门训练 :Fibonacci数列

问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1.当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式 输入包含一个整数n. 输出格式 输出一行,包含一个整数,表示Fn除以10007的余数. 说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单. 样例输入 10 样例输出 55 样例输入

蓝桥杯入门训练——Fibonacci数列

果然是好长时间没有刷题,脑袋都秀逗了.所以说刷题是日常必需品,不能断啊, 因为蓝桥杯还有一个月左右时间,所以又开始了我的刷题道路,但是自从到了4208之后就没太怎么刷题了,也就是说有一个学期没有刷题了. 真的是有些简单的题在很多简单的地方又错了. 从现在开始要经常刷题,摆在你面前的就是刷刷刷!!! 蓝桥网练习系统入门训练 就没有让我省心. 难道是智商又退了吗. 这道题我硬是交了四五遍啊!!! 第一遍 超时  直接计算出了f(n)然后再求的模10007, 原来是我把题目想的太简单了! #inclu

算法-蓝桥杯习题(七)

蓝桥杯习题 蓝桥杯练习系统习题加答案,总共分为6部分,90%习题使用C语言解答,部分使用C++或者Java.大部分习题为搜索参考或者别人提供所得,不足之处在所难免,恳请批评指正(预计200多题,习题仅供学习交流) 目录 算法训练(详见 算法-蓝桥杯习题(一))Go 算法训练(详见 算法-蓝桥杯习题(二))Go 算法提高(waiting...) 历届试题(详见 算法-蓝桥杯习题(六))Go 历届试题(详见 算法-蓝桥杯习题(七))Go 蓝桥杯练习系统评测数据 链接: http://pan.baid