这里是笔者近期学习的一下关于搜索的垃圾小剪枝,这里做一个整理,总结一下知识
下面给出一些例题:
一:非常报数
问题描述
摩尔们的整队报数,比较特别。第一个摩尔报数为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
数据规模
0<n<=30
解析:
这题的暴搜几乎没有实现难度,但是得剪枝,QWQ
如果要剪枝的话,我们无非是从过去或未来开始构思,但是在这道题中,是比较适合将病枝扼杀在摇篮里的——思考未来——按题意给出两种极端情况——全是加或全是减,过小或过大都是没救,全部剪掉
代码:
#include <bits/stdc++.h>
using namespace std;
int n,s;
long ans = 0;
int a[35];
int inc(int a,int b) //加的极端情况
{
int total = 0;
for (int i = a; i <= n; i++)
b++, total += b;
return total;
}
int dec(int a,int b) //减的极端情况
{
int total = 0;
for (int i = a; i <= n; i++)
b--, total += b;
return total;
}
void