L3-001 凑零钱 (dfs) 代码段有详细解析

L3-001 凑零钱 (30 分)

韩梅梅喜欢满宇宙到处逛街。现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债。韩梅梅手边有 104 枚来自各个星球的硬币,需要请你帮她盘算一下,是否可能精确凑出要付的款额。

解题思路:

将所有硬币用vector从小到大排序;(保证最小序列的可能)

用dfs对其进行遍历查找符合条件的第一个序列(最小序列)

#include<bits/stdc++.h>
using namespace std;
vector<int> v,temp;//存储所有硬币和存储符合条件的硬币 
int flag=0,flag2=0;//标记找到符合序列和标记总金额超过规定金额 
int n,m;
void DFS(int n,int sum)//n:第n个硬币  sum:目前总金额 
{
	if(sum==m) //说明已经找到了 
	{
		flag=1;
		return ;
	}
	if(sum>m)//用flag2标记,表示后面的就不用找了 
	{
		flag2=1;
		return ;
	}
	for(int i=n+1;i<v.size();i++)
	{
		temp.push_back(v[i]);//递归前将当前硬币金额录入 
		DFS(i,sum+v[i]); 
		if(flag) return;//找到 
		temp.pop_back();//如果不符合条件就回溯(有点难理解,后面有例题) 
		if(flag2)//后面的更大 
		{
			flag2=0;//要置零,重复利用 
			break;//直接退出 
		}
	}
	
}
int main(void)
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		int a;
		cin>>a;
		v.push_back(a);
	}
	
	//测试点6  所有钱都不够 
	int sum=0;
	for(int i=0;i<v.size();i++)
	{
		sum+=v[i];
	}
	if(sum<m) 
	{
		cout<<"No Solution";
		return 0;
	}
	
	
	sort(v.begin(),v.end());//排序以后,第一个满足条件的序列一定是最小序列 
	for(int i=0;i<v.size();i++)
	{
		temp.push_back(v[i]);//先录入 
		DFS(i,v[i]);
		//只要有符合条件的或者第一个硬币金额就大于总金额就退出(因为vector是从小到大排序的) 
		if(flag||flag2) break;
		temp.pop_back();//不满足再回溯 
	}
	int flag1=0;//按条件输出空格 
	if(flag) 
	{
		for(int i=0;i<temp.size();i++)
		{
			if(flag1) cout<<" ";
			cout<<temp[i];
			flag1=1;
		}
	}
	else cout<<"No Solution";
	return 0;
}

关于dfs的回溯可以用这么一道题理解:

L2-038 病毒溯源 (25 分)__Dawn__的博客-CSDN博客

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

头秃不是梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值