P1874 快速求和

题目

题目

思路

这道题目其实挺有意思,一个1年+的OIer第一眼就能想到dfs并在20mins以内打出暴力,但是我们发现……TLE了,所以我们需要剪枝。

首先显然如果一开始不要+号就相等,直接一个0,退出,(10pts,不要dfs)

接下来我们发现,如果全部加起来(设长度为m,用m-1个加号)都>n,显然无解

同理,用上面的方法,可以进行剪枝:当前dfs到第x位,若前面的和+后面的所有数之和>n,可以直接回溯。

由数据范围可知,每一个加数长度必须<6。
好了,这就够了,上code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
long long ans=0x7fffffff,n,m;
string a;
long long f1(long long x)
{
    
    
	long long u=0;
	for (int i=x;i<=m;i++) u+=a[i]-'0';
	return u;
}
long long ws(long long x,long long y)
{
    
    
	long long u=0;
	for (int i=x;i<=y;i++) u=u*10+a[i]-'0';
	return u;
}
void dfs(long long x,long long s,long long last,long long jia)
{
    
    
	if (x>m)
	{
    
    
		s+=ws(last,m);
		if (s==n) ans=min(ans,jia);
		return;
	}
	if (s+ws(last,x)>n) return;
	if (jia>ans) return;
	if (x-last+1>6) return;
	if (f1(last)+s>n) return;
	dfs(x+1,s+ws(last,x),x+1,jia+1);
	dfs(x+1,s,last,jia);
}
int main()
{
    
    
	cin>>a>>n;
	m=a.size()-1;
	if (ws(0,m)==n)
	{
    
    
		cout<<0;
		return 0;
	}
	dfs(0,0,0,0);
	if (ans==0x7fffffff) cout<<-1;
	else cout<<ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_49843717/article/details/113843414