开赛前对于dfs的见解

dfs对于大部分初学者都是一个很抽象的搜索方法,它算是暴力枚举,但是并没有暴力枚举如此直观,理解起来也比暴力枚举难不少。这篇文章主要针对与近期蓝桥杯比赛中做到的一个题目,来发表一下自己对dfs的理解。

题目在这

首先拿到这个题目我个人是首先想到贪心的,因为我们想最好能让最大数位的数字变成9,不然就让最大数位的数字尽量的大,但是显然有个问题,从逻辑上来讲,因为a,b两个操作我们无法确定优先使用哪一种一定可以得到最大的数,比如4111,如果a=5,b=5,我们如果按照a优先来算可以得到优解为9999,但是如果按照b优先我们就得不到,要知道,每一位数字都需要考虑是a优先还是b优先,因此时间复杂度为2的n次方,显然很炸。因此我们会采用dfs+贪心的策

略深度搜索每一种可能的最大值。

算法思想:我们首先对于a操作,深度搜索,保证每一位数字都是只是用a操作下的最大值,然后我们再去深度搜索b操作,如果这个数位用b操作,看会不会得到更优解,当然此时对于当前位置后面的数,dfs会自动再去重复上边的操作(先a,后b)这样去递归搜索。

总结下来,dfs搜索的本质其实就是:先a后b,不断循环更新当前的数,即使使用b操作更改了当前数位,后边的数位仍然是先a后b去操作。

当然这个题说的是最多使用a次1操作,b次2操作,所以这两次操作不一定要做完,只要能保证到达最大即可。

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
string s;
ll a,b;
ll ans;
void dfs(ll x,ll res){
	ll t=s[x]-'0';
	if(s[x]){
		ll c=min(a,9-t);
		a-=c;
		dfs(x+1,res*10+t+c);
		a+=c;
		if(t<b){
			b=b-(t+1);
			dfs(x+1,res*10+9);
			b+=(t+1);
		}
	}
	else {
		ans=max(ans,res);
	}
}
void solve(){
	cin>>s;
	cin>>a>>b;
	dfs(0,0);
	cout<<ans;
	 
} 
int main(){
	solve();
	return 0;
	
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值