【题目描述】
摩尔们的整队报数,比较特别。第一个摩尔报数为0,从第二摩尔开始,报数为它前面摩尔报数加1或者减1。
如此这样n个摩尔报数的情况,形成多种数列。譬如,有4个摩尔报数,所有可能的报数数列共有如下8种:
0 1 2 3
0 1 2 1
0 1 0 1
0 1 0 -1
0 -1 0 1
0 -1 0 -1
0 -1 -2 -1
0 -1 -2 -3
对于每一种数列,都有其对应的各项之和。以上8种数列中,对应的和为6、4、2、0、0、-2、-4、-6 。其中和为0的有2种。
现在想知道的是n个摩尔排成一列,按照摩尔报数规则报数,报数形成的数列之和为s的情况有多少种?
【输入格式】
共一行,两个正整数,分别为n和s。
【输出格式】
一个数x,表示n个摩尔报数,共有x种数列之和为s。
【样例输入】
4 0
【样例输出】
2
【数据范围】
n<=30
【分析】
带剪枝的搜索,如果当前的和怎么增加/减少都无法达到输入的s就退出。
#include<bits/stdc++.h>
using namespace std;
const int N=35;
int a[N];
int n,s,ans=0;
void dfs(int step,int sum){
if (step>n){
if (sum==s) ans++;
return;
}
int k=n-step+1;
if (sum+(2*a[step-1]+1+k)*k/2<s) return;
if (sum+(2*a[step-1]-1-k)*k/2>s) return;
a[step]=a[step-1]+1;dfs(step+1,sum+a[step]);
a[step]=a[step-1]-1;dfs(step+1,sum+a[step]);
}
int main(){
cin>>n>>s;
a[1]=0;
dfs(2,0);
printf("%d",ans);
}