首页 > 其他分享 >最短路好题整理

最短路好题整理

时间:2022-11-27 21:24:01浏览次数:52  
标签:le dist int 短路 好题 整理 include sum equiv

[ABC077D] Small Multiple

题意:

给定一个整数 \(K\)。求一个 \(K\) 的正整数倍 \(S\),使得 \(S\) 的数位累加和最小。

\(2 \le K \le {10}^5\)
\(K\) 是整数。

思路

只看题目完全看不出来的 模数最短路

我们约定

  • \(sum[x]\) 表示 \(x\) 的数位和;

  • \(f[i]\) 为 \(\min{sum[x](x\equiv i\pmod k)}\),表示在模 \(k\) 余 \(i\) 的所有自然数中的最小数位和。

即把所有的自然数按照模 \(k\) 的结果分成 \(k\) 类 \(0, 1, 2, \dots (k - 1)\)

根据题意可以发现:

  • 题目中的 \(k \geq 2\),也就是说,对于 \(f[1]\) 而言,无论是什么数,\(1\) 一定是最小的,因为如果比 \(1\) 还小就是 \(0\) 了。

以 \(f[1] = 1\) 为跳板继续思考:

  • 假如我们有一种方法可以让所有的 \(f[i]\) 从 \(f[1]\) 转移过来就可以轻松求出答案 \(f[0]\) 了。

有一个很朴素的想法:

  • 对于一个数 \(x(x \equiv i\pmod k)\),它 \(+1\) 后,一定满足 \(x'(x'\equiv i + 1\pmod k)\),用公式写出来即为 \(sum[x] \le sum[(x + 1)\bmod k] + 1\)

  • 对于一个数 \(x(x \equiv i\pmod k)\),它 \(\times 10\) 后,即变为 \(\overline{x0}\),一定满足 \(x'(x'\equiv i\pmod k)\),用公式写出来即为 \(sum[x] \le sum[(10x)\bmod k]\)。

由于在模 \(k\) 意义下,\(f[i] = sum[x](x\equiv i\pmod k)\),因此将上述公式整理后,得:

\[\left\{ \begin{aligned} f[i] &\le f[i + 1] + 1\\ f[i] &\le f[10\times i] \end{aligned} \right. \]

这不就是差分约束吗!

因此我们将所有的模数可能性视作一个点,将 \(i\) 到 \(i + 1\) 连一条长度为 \(1\) 的边,\(i\) 到 \(10i\) 连一条长度为 \(0\) 的边,这种情况我们不用跑 \(\text{SPFA}\)了,因为从 \(1\) 开始必定能遍历到所有点,并且权值只有 \(0, 1\),直接跑一遍 \(\text{双端队列BFS}\) 即可,最后 \(f[0]\) 即为答案。

模拟

在模 \(7\) 意义下,建出来的图如下:

走法:1-3-2-6-0

Show the Code
// Problem: [ABC077D] Small Multiple
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/AT_arc084_b
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Author: Moyou
// Copyright (c) 2022 Moyou All rights reserved.
// Date: 2022-11-27 19:53:48

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <queue>
#include <stack>
#define x first
#define y second
#define INF 0x3f3f3f3f
#define speedup (ios::sync_with_stdio(0), cin.tie(0), cout.tie(0))
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int N = 1e5 + 10, M = 2e5 + 10;

int h[N], ne[M], e[M], w[M], idx;
int k;
int dist[N];
bool st[N];
void add(int a, int b, int c)
{
    e[++idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx;
}

void bfs(int s)
{
    memset(dist, 0x3f, sizeof dist);
    dist[s] = 1;
    deque<int> q;
    q.push_front(s);
    while (q.size())
    {
        auto t = q.front();
        q.pop_front();
        if (st[t])
            continue;
        st[t] = 1;
        for (int i = h[t]; ~i; i = ne[i])
        {
            int j = e[i];
            if (dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i];
                if (w[i] == 0)
                    q.push_front(j);
                else
                    q.push_back(j);
            }
        }
    }
}

int main()
{
    memset(h, -1, sizeof h);
    cin >> k;
    for (int i = 1; i <= k; i++)
    {
        add(i, (i + 1 > k ? 1 : i + 1), 1);
        add(i, (i * 10 % k), 0);
    }
    bfs(1);
    cout << dist[0] << endl;
    return 0;
}

标签:le,dist,int,短路,好题,整理,include,sum,equiv
From: https://www.cnblogs.com/MoyouSayuki/p/16930529.html

相关文章

  • 拓端tecdat|python编程指导使用马尔可夫决策过程(MDP)动态编程来解决最短路径强化学习
    python中使用马尔可夫决策过程(MDP)动态编程来解决最短路径强化学习问题 在强化学习中,我们有兴趣确定一种最大化获取奖励的策略。假设环境是马尔可......
  • 以前整过的一些好题
    不积累一下套路恐怕是不行。。。还是整一哈吧LuoguP8578dfs序构造题链接大意是给n个节点的树每个点上一个权值,是一个1~n的排列,要求最小化$f=\sum_{i=1}^{n}R_i,$,Ri是以......
  • 【算法入门&搜索法】走迷宫|单源最短路径1
    文章目录​​......
  • [边数限制最短路 倍增floyd 矩阵优化]Cow Relays G
    [边数限制最短路倍增floyd矩阵优化]CowRelaysG题目思路边数限制的最短路?bellman_ford可以拿来解决边数<=k的最短路,但这题是边数恰好为k,可以通过奇妙操作改成恰好经过k......
  • [NEFU 数据结构] 第 2 章 线性表 知识点整理
    [NEFU数据结构]第2章线性表知识点整理阅读须知需求指向:此博客用于应付NEFU数据结构考试,基于题目进行整理,不适合想深入学习数据结构与算法艺术的同学。前置知识:C语言......
  • [NEFU]数据结构 知识点整理和代码实现
    [NEFU]数据结构知识点整理和代码实现Author:2020-计6-zslID:Fishingrod阅读须知需求指向:此博客用于应付NEFU数据结构考试,基于题目进行整理,不适合想深入学习数据结构与算法......
  • [NEFU 数据结构] 第 1 章 绪论 知识点整理
    [NEFU数据结构]第1章绪论知识点整理阅读须知需求指向:此博客用于应付NEFU数据结构考试,基于题目进行整理,不适合想深入学习数据结构与算法艺术的同学。前置知识:C语言参......
  • Git整理提交记录
    前言开发人员有时会说“我想要把这个提交放到这里,那个提交放到刚才那个提交的后面”,而接下来就讲的就是它的实现方式。gitcherry-pick命令形式为:gitcherry-pic......
  • 资深java面试题及答案整理(四)
     资深java面试题及答案整理(四)7.编写Java程序时,如何在Java中创建死锁并修复它?经典但核心Java面试问题之一。如果你没有参与过多线程并发Java应用程序的编码,你......
  • 资深java面试题及答案整理(五)
     8.如果你的Serializable类包含一个不可序列化的成员,会发生什么?你是如何解决的?任何序列化该类的尝试都会因NotSerializableException而失败,但这可以通过在Java中为st......