蓝桥杯 波动数列

题目地址: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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值