51nod 减减数1425

题意:

1425 减减数
1.0 秒 131,072.0 KB 80 分 5级题
初始给定一个整数n。每次可以对其做一个操作,这个操作是将n减去他其中的某一位。得到新的一个数字n’,然后继续操作,直到他变成0为止。

比如24这个例子,24 → 20 → 18 → 10 → 9 → 0

输入
单组测试数据。
第一行有一个整数n(0 ≤ n ≤ 10^12)
输出
输出一个整数表示使得n变成0最少的操作步数。.
输入样例
24
输出样例
5

思路:

1.我的想法:

首先,我们可以先看一下最朴素的算法,那么就是每次都进行分解数字,然后选择最大的数,删掉删掉,很明显n是1e12的范围,不能说一定会T掉,大概率会T掉。。。

然后就要想办法了,首先,我们应该明确肯定每次要减掉最大的,而且前面高位的最大值会对后面低位造成影响。比如1911,百位上的9会对十位上的1和个位上的1造成影响。

我是在哪里出错了呢,当然就是剩下的部分的处理出错了

2.我的想法

我本来是想搜索来着,但是是正着搜索,但是题目要求是这个操作是将n减去他其中的某一位。 但是好像判断有点困难,也不太行

3.正解:

没想到的就是真正解法就是倒着来搜索记忆化搜索

dfs(n , mx)表示当前要处理的数是n,mx是比n的最高位还要高的位的最大值

返回值是pair<long long , long long>类型的,first代表操作次数,second代表将该部分变为0中多余的部分。

记忆化搜索

代码实现:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<stdlib.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<math.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pii;
const int maxn = 2e5 + 5;

ll n;
map<pii,pii>mp;


pii dfs(ll n,ll mx){
	//n表示的当前需要处理的数,mx是比n的最高位还要高的位的最大值
	//返回值为pair类型,first表示操作次数,second表示将该部分变为0的过程中多余的部分
	if(mp[make_pair(n,mx)].first) return mp[make_pair(n,mx)];
	if(n < 10) return make_pair((n > 0)||(mx > 0),max(n,mx) - n);
	ll m = 1;
	while(m <= n / 10) m = m * 10;
	ll p = n / m;
	m = m * p;
	pii a = dfs(n - m,max(p,mx)),b = dfs(m - a.second,mx);
	return mp[make_pair(n,mx)] = make_pair(a.first + b.first,b.second);
}

int main(){
	scanf("%lld",&n);
	printf("%lld\n",dfs(n,0).first);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值