栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

快速加法(C++)[DFS]

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

快速加法(C++)[DFS]

题目:

Description

小小秦是小秦的弟弟,他才学会加法。

小秦现在想考试一下弟弟对加法的掌握程度,但他又不想出平时学校老师出的那些题

于是他给出一串数字S,再给出一个整数N。

问弟弟这样一个问题 在S中添加几个加号,可以使得表达式的结果为S。

例如 S="303",N=6 则只最少只要一个加号就可以了即3+03=6

S="1110",N=3 则最少要加3个加号,即1+1+1+0=3

Format

Input

第1行:1个字符串S(1 ≤ S的长度 ≤ 40) 和1个整数N(N≤100000)。

S和N用1个空格分隔。

Output

第1行:1个整数K,表示最少的加法次数让S等于N。

如果怎么做都不能让S等于N,则输出-1。

Samples

【输入样例】

输入数据 1
99999 45
输出数据 1
4
 思路:

这道题采用(深度优先)算法。

我们可以模拟添加加号的位置:

用指向当前数, 

记下当前的累加和(并不一定加到的深度),

再记下当前的加数

和加号的个数(拼音大法)

注意,关于有两种操作:

是会延长的,它可以与当前指向的数合并,但不会累加,不然会很麻烦,因为有记下累加和就够了。如:当前,当前指向数字,则可以与合并为;

加到里更新累加和,此时变成指向的数,此时加号个数也要加一

 我们做就可以按这两种操作来做 

代码:

#include
using namespace std;
const int N= 210;
string s;
int len;
int m;
int ans=INT_MAX;//答案 
int zhuan(char ss) {//转换器,将字符型转成整型 
	if(ss=='0') return 0;
	if(ss=='1') return 1;
	if(ss=='2') return 2;
	if(ss=='3') return 3;
	if(ss=='4') return 4;
	if(ss=='5') return 5;
	if(ss=='6') return 6;
	if(ss=='7') return 7;
	if(ss=='8') return 8;
	if(ss=='9') return 9;
}
void dfs(int dep,int sum,int jia,int now_num) {
	if(sum>m) return ;//如果sum比要求的和m还大,可以return了 
	if(dep==len) {//如果已经遍历完这串数 
		if(sum+now_num==m) //且sum为要求的和m 
		    ans=min(jia,ans);//更新答案 
		return ;//一定要return 
	}
// 01DFS: 
	dfs(dep+1,sum,jia,now_num*10+zhuan(s[dep]));
	//now_num它可以与当前dep指向的数合并
	dfs(dep+1,sum+now_num,jia+1,zhuan(s[dep]));
	//也可以把now_num加到sum中,此时jia+1 
}
int main() {
	cin>>s>>m;
	len=s.size();//获取长度 
	dfs(0,0,0,0); 
	if(ans==INT_MAX) puts("-1");
	else
		cout<

对,你没有看错,了,这说明没完

于是我又加了几个剪枝:

 正解:
#include
using namespace std;
const int N = 210, M = 100010;
string s;
int len;
int m;
int ans = INT_MAX;
int bs[N];

int ss[M]; 
 
int zhuan (char ss)
{
	if (ss == '0') return 0;
	if (ss == '1') return 1;
	if (ss == '2') return 2;
	if (ss == '3') return 3;
	if (ss == '4') return 4;
	if (ss == '5') return 5;
	if (ss == '6') return 6;
	if (ss == '7') return 7;
	if (ss == '8') return 8;
	if (ss == '9') return 9;
}
void dfs (int dep, int sum, int jia, int now_num)
{
	if (sum > m) return ;
	if (now_num + sum > m) return ;
	if (dep == len)
	{
		if (sum + now_num == m) ans = min (jia, ans);
		return ;
	}

	if (sum + bs[len - 1] - bs[dep] > m) return ;
	//如果把dep到末位的数一个个加起来都大于m的话就return吧 
	if (ss[sum])//如果不是最优的,return; 
		if (ss[sum] < jia) return ;
	ss[sum] = jia;//否则更新最优的 
	
	dfs (dep + 1, sum, jia, now_num * 10 + zhuan (s[dep]) );
	dfs (dep + 1, sum + now_num, jia + 1, zhuan (s[dep]) );
}
int main()
{
	cin >> s >> m;
	len = s.size();
	bs[0] = zhuan (s[0]);
	for (int i = 1; i < len; i++)//做前缀和 
		bs[i] = bs[i - 1] + zhuan (s[i]);
	dfs (0, 0, 0, 0);
	if (ans == INT_MAX) puts ("-1");
	else
		cout << ans << endl;
	return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1025260.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号