蓝桥杯 波动数列

  • Post author:
  • Post category:其他


题目地址:

https://www.dotcpp.com/oj/problem1449.html。刚看到这个题目第一个想法就是深搜

#include <iostream>
using namespace std;
long long n, s, a, b;
long long sum;
long long cnt = 0;
long long mo = 100000007;
int dfs(long long nn, long long rn) {
// cout << "dfs ?" << nn << ", " << rn << endl;
	sum += nn;
	if(rn == 0) {//能用的减数或加数用完了?
//cout << "sum ? " << sum << endl;
		if(sum == s) {
			sum -= nn;//减去恢复 以便再次遍历 ,测试 5 10 2 3 就发现有差异 (有的情况前面相同而后面不同)?
// cout << "cnt" << endl;;
			cnt++;//种数?
			cnt %= mo;
			return 1;
		} else {
			sum -= nn;//减去恢复 以便再次遍历 ,
			return 0;
		}
	}
	dfs(nn + a, rn - 1);
	dfs(nn - b, rn - 1);
	sum -= nn;//减去恢复 以便再次遍历 ,
}
int main(void) {
	cin >> n >> s >> a >> b;
//dfs(2, 3);
	for(long long i = s - n * a; i < s + n * b; i++) {
		sum = 0;
		dfs(i, n - 1);//从第一个数的最值[s-n*a,s+n*b]之间测试怎样加减达到给定的和值 ,所以后面的数是n-1?
	}
	cout << cnt << endl;
	return 0;
}

这个题目的最优解是用到01背包问题,滚动数组,下面看两位大佬的博客:

https://blog.csdn.net/wr132/article/details/43861145,


https://blog.csdn.net/more_ugly_less_bug/article/details/54957478



版权声明:本文为Zhangjiangyuan原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。