hdu-6071 Lazy Running

In HDU, you have to run along the campus for 24 times, or you will fail in PE. According to the rule, you must keep your speed, and your running distance should not be less than K meters.

There are 4 checkpoints in the campus, indexed as p1,p2,p3 and p4.
Every time you pass a checkpoint, you should swipe your card, then the
distance between this checkpoint and the last checkpoint you passed will
be added to your total distance.

The system regards these 4 checkpoints as a circle. When you are at checkpoint pi, you can just run to pi−1 or pi+1(p1 is also next to p4). You can run more distance between two adjacent checkpoints, but only the distance saved at the system will be counted.

Checkpoint p2
is the nearest to the dormitory, Little Q always starts and ends
running at this checkpoint. Please write a program to help Little Q find
the shortest path whose total distance is not less than K

.

InputThe first line of the input contains an integer T(1≤T≤15), denoting the number of test cases.

In each test case, there are 5 integers K,d1,2,d2,3,d3,4,d4,1(1≤K≤1018,1≤d≤30000), denoting the required distance and the distance between every two adjacent checkpoints.OutputFor each test case, print a single line containing an integer, denoting the minimum distance.Sample Input

1
2000 600 650 535 380

Sample Output

2165

Hint

The best path is 2-1-4-3-2.

OJ-ID:
hdu-6071

author:
Caution_X

date of submission:
20191024

tags:
dp+dijkstra

description modelling:
有四个点1,2,3,4形成环1-2-3-4-1,四条边的权值表示距离,问能否找到一条路径从点2出发回到点2并且权值之和大于K

major steps to solve it:
w=min(d1,d2),其中d1是1,2之间的距离,d2是2,3之间的距离
假设有符合条件的最小权值和P,那么就会有最佳的P-w
设dp[i][j]:=从2出发到达i点时的最小权值和,其中j是权值和%(2*w),之所以%(2*w)是因为从2出发再回到2权值和最少2*w
同样是从2到达i点,不同的j表示不同的路径,若j相同但是从2到i的权值和不同,则选择权值和小的
(1)dijkstra更新dp[i][j]
(2)判断dp[2][j]是否大于K,若小于K则不足之处用w填充

AC code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const ll INF = 1e18;
const int MAXN = 6e4 + 10;
vector<P> G[MAXN];
ll d[5][MAXN];
void dijkstra(ll w, int s) {
    for(int i = 1; i <= 4; i++) {
        fill(d[i], d[i] + w, INF);
    }
    priority_queue<P, vector<P>, greater<P> >q;
    q.push(P(0, s));
    d[s][0] = 0;
    while(!q.empty()) {
        P p = q.top(); q.pop();
        int v = p.second;
        if(p.first > d[v][p.first % w]) continue;
        for(int i = 0; i < (int)G[v].size(); i++) {
            P e = G[v][i];
            ll dist = e.first + d[v][p.first % w];
            if(dist < d[e.second][dist % w]) {
                d[e.second][dist % w] = dist;
                q.push(P(dist, e.second));
            }
        }
    }
}
int main() {
    int T;
    cin >> T;
    while(T--) {
        memset(G, 0, sizeof G);
        ll K, d1, d2, d3, d4;
        cin >> K >> d1 >> d2 >> d3 >> d4;
        G[1].push_back(P(d1, 2));
        G[2].push_back(P(d1, 1));
        G[2].push_back(P(d2, 3));
        G[3].push_back(P(d2, 2));
        G[3].push_back(P(d3, 4));
        G[4].push_back(P(d3, 3));
        G[4].push_back(P(d4, 1));
        G[1].push_back(P(d4, 4));
        ll w = 2 * min(d1, d2);
        dijkstra(w, 2);
        ll ans = INF;
        for(ll i = 0; i < w; i++) {
            if(d[2][i] >= K) {
                ans = min(ans, d[2][i]);
            } else {
                ll nd = K - d[2][i];
                ans = min(ans, d[2][i] + nd / w * w + (nd % w > 0) * w);
            }
        }
        cout << ans << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/cautx/p/11735479.html

时间: 2024-10-26 23:35:04

hdu-6071 Lazy Running的相关文章

hdu 6071 Lazy Running(同余最短路)

题目链接:hdu 6071 Lazy Running 题意: 给你4个点,每两个相邻点有一个距离,现在让你在这四个点来回跑步,从2开始,最后回到2,问你找一个距离ans,ans>=k,问最小的ans是多少. 题解: Claris的官方题解: 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=(a);i<=(b);++i) 3 using namespace std; 4 using ll=long long; 5 6 co

HDU 6071 Lazy Running (同余最短路)

Lazy Running Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 101    Accepted Submission(s): 40 Problem Description In HDU, you have to run along the campus for 24 times, or you will fail in PE

HDU 6071 Lazy Running (同余最短路 dij)

Lazy Running Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 1384    Accepted Submission(s): 597 Problem Description In HDU, you have to run along the campus for 24 times, or you will fail in

HDU 6071 Lazy Running(最短路)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6071 [题目大意] 给出四个点1,2,3,4,1和2,2和3,3和4,4和1 之间有路相连, 现在从2点出发,最后回到2点,要求路径大于等于K,问路径长度最短是多少 [题解] 取一条与2相连的权值最小的边w. 若存在一条从起点到终点的长度为k的路径, 那么必然存在一条长度为k+2w的路径,只要一开始在那条边上往返走就好了. 设dij表示从起点到i,路径长度模2w为j时,路径长度的最小值. 用最短

HDU 6071 同余最短路 spfa

Lazy Running Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 657    Accepted Submission(s): 284 Problem Description In HDU, you have to run along the campus for 24 times, or you will fail in P

HDU6071 Lazy Running

链接:http://acm.hdu.edu.cn/showproblem.php?pid=6071 挺晚了,还是决定写一下题解~~~ 题意:给你四个点,组成一个圈,求从2出发再回到2的所有路径中大于K的最小值: 思路:其实跟前一篇大容量背包一样利用同余系最短路求: 可以这么理解,我对满足要求的所有路径分类,标准是模m的值为j(0=<j<m)的所有路径分到一组,而dis[i][j]表示满足从1到i模m为j的最小 路径,因为我们求的是最短路径,对于一组同余系,我记录最小的解即可,m是从1出来的两条

hdu 3349 lazy gege

lazy gege Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 902    Accepted Submission(s): 348 Problem Description Gege hasn't tidied his desk for long,now his desk is full of things. This mornin

【最短路】【spfa】hdu6071 Lazy Running

给你一个4个点的环,问你从2号点出发, 再回到2号点,长度>=K的最短路是多少.环上的边长度不超过30000. 跑出来所有dis(2,j)以后,然后for一遍j,根据dis(2,j)+t*2*w>=K,解出来对于每个j而言最小的t,然后尝试更新答案即可.如果dis(2,j)已经大于等于K了,那直接用其尝试更新答案. 跟CDOJ1633很像. #include<cstdio> #include<queue> #include<algorithm> #inclu

noip考前抱佛脚 数论小总结

exCRT 求解韩信点兵问题,常见的就是合并不同\(mod\). 先mo一发高神的板子 for(R i=2;i<=n;++i){ ll Y1,Yi,lcm=Lcm(p[i],p[1]); exgcd(p[1],p[i],a[i]-a[1],Y1,Yi); add(a[1],mul(p[1],Y1,lcm),lcm),p[1]=lcm; } 思想是合并方程组,现在假设我们要求解的是: \[x-p_0*y_0=a_0\]\[x-p_i*y_i=a_i\] \(x\)是实际的值,显然有: \[p_0*