题解 | #1002.Shortest path# 2023杭电暑期多校9

1002.Shortest path

签到题 记忆化搜索

题目大意

给定一个正整数 n n n ,可以对其进行以下操作:

  1. 如果 n n n 能被 3 3 3 整除,则可以使 n = n / 3 n=n/3 n=n/3 ;
  2. 如果 n n n 能被 2 2 2 整除,则可以使 n = n / 2 n=n/2 n=n/2 ;
  3. 使 n = n − 1 n=n-1 n=n1

求使得 n n n 变成 1 1 1 的最少操作次数

解题思路

将样例Output输出即可

这题不难,但确实精彩()//毕竟……
《钉耙编程”中国大学生算法设计超级联赛》是由hdu自主研发的一款全新开放世界冒险竞赛。竞赛发生在一个被称作“hdu”的幻想世界,在这里,被编译器选中的人将被授予“C++”,导引代码之力。你将扮演一位名为“acmer”的神秘角色,在自由的打题中邂逅性格各异能力独特的STL容器,和他们一起击败强题,找回AC的代码

不闹了,解题吧()

不难看出操作 3 3 3 的收益最低,是不满足操作 1 , 2 1,2 1,2 的时候凑条件用的。
而由于只允许整除,操作 1 , 2 1,2 1,2 的优劣性不好评估(因为要夹杂操作 3 3 3 而不单纯是减少的量的区别),因此每次对本次进行的两种操作方案进行比较。

按以下操作递归处理 n n n

  1. 如果 n = 1 n=1 n=1 ,则返回 0 0 0
  2. 进行若干次(可能0次)操作 3 3 3 使得 n n n 能被 2 2 2 整除,执行操作 2 2 2
  3. 进行若干次(可能0次)操作 3 3 3 使得 n n n 能被 3 3 3 整除,执行操作 1 1 1

由于数据范围的关系,传统的DFS会超时,因此需要使用记忆化搜索
即每次计算完某个数(记为 x x x )的结果,将其保存下来,后续搜索 x x x 时就无需继续搜索到底部,直接输出这个数的结果即可
记忆化搜索可以用 map 实现,频繁读取而不考虑元素顺序的可以使用 unordered_map ,有效降低时间空间复杂度

题解 | #1002.Shortest path# 2023杭电暑期多校9_第1张图片
下面两份使用了 map ,代码完全一致;上面一份仅仅将 map 改为了 unordered_map

时间复杂度

O ( t log ⁡ 2 n ) O(t\log^2n) O(tlog2n)

参考代码

参考代码为已AC代码主干,其中部分功能需读者自行实现

unordered_map mp;
ll dfs(ll n){
    if(n<=1) return 1-n;
    if(mp[n]) return mp[n];
    ll t1,t2;
    t1=n%2+1+dfs(n/2);
    t2=n%3+1+dfs(n/3);
    return mp[n]=min(t1,t2);
}
void solve()
{
    ll n;cin >> n;
    cout << dfs(n) << endl;
}

你可能感兴趣的:(2023杭电多校,算法)