Luo Gu P1280 Nick task explanations dynamic programming / shortest

  • Author: zifeiy
  • Tags: dynamic programming, shortest path

Link Title: https://www.luogu.org/problem/P1280
Title effect:
with k task distribution in the first to the n time point n, the i-th task on the first \ (P_i \) begins minutes, duration \ (T_i \) minutes, the task will be the first (P_i + T_i-1 \) \ end minutes.
If you are i idle time, but this time there is at least one task at a time i start, then you must select a task in which you want to do;
if i moment you are free, without any one task at a time i start, then you can be at the moment i idle.
Beg you most, what time is free.

Dynamic Programming Solution

We make \ (f [i] \) starts from the moment i to the maximum number of idle time during this time of the end of time n.
Then we can iterate i from 1 to n time to time i:

  • If no task is started at the time i, then \ (F [i] = F [i +. 1] +. 1 \) ;
  • Otherwise \ (F [I] = \ max (F [I + T_j]) \) , wherein, \ (T_j \) corresponding to all \ (I P_j == \) .

Codes are as follows:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int n, k, p, t, f[maxn];
vector<int> g[maxn];
int main() {
    cin >> n >> k;
    while (k --) {
        cin >> p >> t;
        g[p].push_back(t);
    }
    for (int i = n; i >= 0; i --) {
        int sz = g[i].size();
        if (sz == 0) f[i] = f[i+1] + 1;
        else {
            for (int j = 0; j < sz; j ++)
                f[i] = max(f[i], f[ i + g[i][j] ]);
        }
    }
    cout << f[1] << endl;
    return 0;
}

Shortest solution

This idea from the blog tong_xz Gangster

The point in time as the point in FIG.
P from the first minute, duration T P-minute tasks regarded from the point to the point P + T T is not even a right side. (The starting point is the starting edge time of the task, the end is the end of the next minute mission time)
if a point in the end did not have a degree, a point even the back side of the right side is zero (no work to do, this minutes he can catch fish ...)
to run the shortest path to get him at least how long to dry, the answer is (n- shortest result)
if the right edge as the rest of the words with the longest road can do.

Codes are as follows:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int in[maxn], out[maxn], n, k, p, t, dis[maxn];
bool vis[maxn];
vector< pair<int, int> > g[maxn];
queue<int> que;

void spfa() {
    memset(dis, -1, sizeof(int) * (n+2));
    dis[1] = 0;
    que.push(1);
    while (!que.empty()) {
        int u = que.front();
        que.pop();
        vis[u] = false;
        int sz = g[u].size();
        for (int i = 0; i < sz; i ++) {
            int v = g[u][i].first, w = g[u][i].second;
            if (dis[v] == -1 || dis[v] > dis[u] + w) {
                dis[v] = dis[u] + w;
                if (!vis[v]) {
                    vis[v] = true;
                    que.push(v);
                }
            }
        }
    }
}

int main() {
    cin >> n >> k;
    while (k --) {
        cin >> p >> t;
        out[p] ++;
        in[p+t] ++;
        g[p].push_back(make_pair(p+t, t));
    }
    for (int i = 1; i <= n; i ++) {
        if (!out[i]) g[i].push_back(make_pair(i+1, 0));
    }
    spfa();
    cout << n - dis[n+1] << endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/codedecision/p/11666325.html