日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

同余最短路(P3403 跳楼机)

發(fā)布時(shí)間:2023/12/4 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 同余最短路(P3403 跳楼机) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

同余最短路

前置

給定m個(gè)數(shù),這m個(gè)數(shù)可以重復(fù)取,問(wèn)最大的這m個(gè)數(shù)不能拼成的數(shù),或者給定一定范圍,范圍里有多少個(gè)數(shù)是這m個(gè)數(shù)可以拼成的,對(duì)于這種問(wèn)題我們可以考慮同余最短路的算法。

P3403 跳樓機(jī)

同余最短路介紹

首先我們要選擇一個(gè)basebasebase作為基底,之后所有的距離就可以描述成a?base+ba * base + ba?base+b

在這題中我們選定xxx作為base。

dis[i]=valuedis[i] = valuedis[i]=value有如下含義:value≡i(modx)value \equiv i \pmod xvaluei(modx),也就是同余的條件下,我們可以到達(dá)的最小的樓層,這樣我們剩下的樓層就可以通過(guò)+x+ x+x的操作去訪問(wèn),所以我們最后的可以到達(dá)的樓層也就是∑i=0x?1(h?dis[i])/x+1\sum _{i = 0} ^ {x - 1} (h - dis[i]) / x + 1i=0x?1?(h?dis[i])/x+1,這句應(yīng)該稍加簡(jiǎn)單理解一下就好了。

接下來(lái)我們考慮如何建邊,顯然有i?>(i+y)%xcost=y,i?>(i+z)%xcost=zi - > (i + y) \% x\ cost = y, i -> (i + z) \% x\ cost = zi?>(i+y)%x?cost=y,i?>(i+z)%x?cost=z

所以我們可以對(duì)所有的x∈[0,x?1]x\in [0, x - 1]x[0,x?1],分別同上建立一條邊權(quán)為yyy的,一條邊權(quán)為zzz的邊。然后再去跑一遍最短路,我們就可以得到所有的disdisdis了。

代碼

/*Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> #define mp make_pair #define pb push_back #define endl '\n'using namespace std;typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii;const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x; }void print(ll x) {if(x < 10) {putchar(x + 48);return ;}print(x / 10);putchar(x % 10 + 48); }const int N = 1e5 + 10;ll h, dis[N];bool visit[N];vector<pii> G[N];void spfa() {memset(dis, 0x3f, sizeof dis);queue<int> q;q.push(1);dis[1] = 1, visit[1] = 1;while(q.size()) {int temp = q.front();q.pop();visit[temp] = 0;for(pii i : G[temp]) {if(dis[i.first] > dis[temp] + i.second) {dis[i.first] = dis[temp] + i.second;if(!visit[i.first]) {q.push(i.first);visit[i.first] = 1;}}}} }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);h = read();int x = read(), y = read(), z = read();if(x == 1 || y == 1 || z == 1) {//注意如果有一個(gè)數(shù)為1,必須特判,不然我們跑出來(lái)的最短路dis,將會(huì)重復(fù)計(jì)數(shù)。printf("%lld\n", h);return 0;}for(int i = 0; i < x; i++) {G[i].pb(mp((i + y) % x, y));G[i].pb(mp((i + z) % x, z));}spfa();ll ans = 0;for(int i = 0; i < x; i++) {if(dis[i] <= h) {ans += (h - dis[i]) / x + 1;}}printf("%lld\n", ans);return 0; }

總結(jié)

以上是生活随笔為你收集整理的同余最短路(P3403 跳楼机)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。