zoukankan      html  css  js  c++  java
  • FJUT2019暑假第二次周赛 A题

    A题

    题目链接

    服务器维护
    TimeLimit:1500MS MemoryLimit:128MB
    64-bit integer IO format:%lld
    Problem Description
    Dsc最大的梦想就是有一款属于自己的游戏(不可能的),可以把自己的奇思妙想在虚拟的世界中创造出来,假设Dsc成功了,创造出了一款网游(小作坊的那种),现在为了节省成本,Dsc决定自己维护服务器健康,但总会有没时间的时候。

    假设从S分钟开始,E分钟结束[S,E]这段时间Dsc是没有时间的,这时候Dsc需要找人来维护服务器,当然是有偿的。在[S,E]这段时间中有n个人有空余时间(不一定是全部[S,E])第i个人在ai,bi这段时间有空,共需要ci的管理费。

    现在请帮Dsc算一算,在他没空的时间内[S,E],每天都至少有一个人在管理服务器所需要的最少花费是多少,如果没有任何方案使[S,E]时间内每天都至少有一个人在管理服务器则输出-1;

    Input
    第一行为三个整数n,S,E分别表示有n个人有空,在[S,E]时间内Dsc没空

    接下来有n行,每行3个整数ai,bi,ci分别表示第i个人在[ai,bi]时间内有空,雇佣共需要ci管理费

    1<=n<=1e5

    0<=S<=E<=1e5

    S<=ai<=bi<=E

    1<=ci<=1e5

    Output
    Dsc在没空的时间找人管理服务器所需的最少花费,没有方案则输出-1

    SampleInput
    3 2 4
    2 3 2
    4 4 1
    2 4 4
    SampleOutput
    3

    [思路1]:

    其实这个题目就是一个DP加上线段树维护即可AC, 根据题意容易得知,需要区间全覆盖,那么我们可以考虑先按L从小到大排序维护从[S, R]所花费的最小价值,可得状态为dp[i]代表从[s, i]区间覆盖的最小价值。
    可得状态转移方程为
    dp[i] = min(dp[i], quert_min(l - 1, i - 1)) + w)
    即可AC
    

    附上代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e5 + 15;
    const LL inf = __LONG_LONG_MAX__;
    int n, s, e;
    struct Segtree{
        LL arr[MAXN];
        struct NODE{
            int l, r;
            LL mins;
        }tree[MAXN << 2];
        void build(int root, int l, int r){
            tree[root].l = l, tree[root].r = r;
            if(l == r){
                tree[root].mins = arr[l];
                return ;
            }
            int mid = (l + r) >> 1;
            build(root << 1, l, mid);
            build(root << 1 | 1, mid + 1, r);
            tree[root].mins = min(tree[root << 1].mins, tree[root << 1 | 1].mins);
            return ;
        }
        void update(int root, int num, LL val){
            if(tree[root].l == num && tree[root].r == num){
                tree[root].mins = val;
                return ;
            }
            int mid = (tree[root].l + tree[root].r) >> 1;
            if(num <= mid){
                update(root << 1, num, val);
            }
            else{
                update(root << 1 | 1, num, val);
            }
            tree[root].mins = min(tree[root << 1].mins, tree[root << 1 | 1].mins);
            return ;
        }
        LL query(int root, int l, int r){
            if(tree[root].l >= l && tree[root].r <= r){
                return tree[root].mins;
            }
            int mid = (tree[root].l + tree[root].r) >> 1;
            if(r <= mid){
                return query(root << 1, l, r);
            }
            else if(l > mid){
                return query(root << 1 | 1, l, r);
            }
            else{
                return min(query(root << 1, l, mid), query(root << 1 | 1, mid + 1, r));
            }
        }
    }seg;
    struct Person{
        int l, r;
        LL value;
        friend bool operator< (const Person &a, const Person &b){
            if(a.l == b.l){
                return a.value < b.value;
            }
            else{
                return a.l < b.l;
            }
        }
    }arr[MAXN];
    LL dp[MAXN];
    int main(){
        ios::sync_with_stdio(false);
        cin >> n >> s >> e;
        s += 2, e += 2;
        for(int i = 0; i < n; i ++){
            cin >> arr[i].l >> arr[i].r >> arr[i].value;
            arr[i].l += 2, arr[i].r += 2;
        }
        for(int i = s; i <= e; i ++){
            seg.arr[i] = inf;
            dp[i] = inf;
        }
        for(int i = 0; i < s; i ++){
            seg.arr[i] = 0;
            dp[i] = 0;
        }
        seg.build(1, 1, e);
        sort(arr, arr + n);
        for(int i = 0; i < n; i ++){
            if(seg.query(1, arr[i].l - 1, arr[i].r - 1) != inf){
                dp[arr[i].r] = min(dp[arr[i].r], seg.query(1, arr[i].l - 1, arr[i].r - 1) + arr[i].value);
                seg.update(1, arr[i].r, dp[arr[i].r]);    
            }
        }
        if(dp[e] == inf){
            cout << "-1
    ";
        }
        else{
            cout << dp[e] << endl;
        }
        return 0;
    }
    

    [思路2]:

    对于整个数据进行建图,将区间能互相覆盖的点连接起来,然后跑最短路径
    

    附上代码:

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <ctime>
    #include <cctype>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <list>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <algorithm>
    #include <functional>
    #define lowbit(x) (x&(-x))
    #define rep(i,a,n) for (int i=a;i<=n;i++)
    #define per(i,a,n) for (int i=a;i>=n;i--)
    #define mem(ar,num) memset(ar,num,sizeof(ar))
    #define debug(x) cout << #x << ": " << x << endl
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    const int    prime = 999983;
    const int    INF = 0x7FFFFFFF;
    const LL     INFF =0x7FFFFFFFFFFFFFFF;
    const double pi = acos(-1.0);
    const double inf = 1e18;
    const double eps = 1e-6;
    const LL     mod = 1e9 + 7;
    const int    maxn = 1e6 + 7;
    const int    maxm = 4e6 + 7;
    
    int n, m, first[maxn], sign;
    
    struct Edge{
        int to, w, next;
    }edge[maxn * 2];
    
    void init(){
        for(int i = 0; i <= n; i++){
            first[i] = -1;
        }
        sign = 0;
    }
    
    void addEdge(int u,int v,int w){
        edge[sign].to = v;
        edge[sign].w = w;
        edge[sign].next = first[u];
        first[u] = sign++;
    }
    
    struct Node{
        int to;
        LL cost;
        Node(){}
        Node(int tt, LL cc):to(tt),cost(cc){}
        friend bool operator < (const Node &a, const Node &b){
            return a.cost > b.cost;
        }
    };
    
    LL dist[maxn];
    int vis[maxn];
    
    LL dijkstra(int s, int t){
        for(int i = 0; i <= n; i++){
            dist[i] = INFF;
            vis[i] = 0;
        }
        priority_queue<Node> que;
        que.push(Node(s,0));
        while(!que.empty())
        {
            Node now = que.top();
            //printf("%d
    ",now.to);
            que.pop();
            if(!vis[now.to]){
                vis[now.to] = 1;
                dist[now.to] = now.cost;
                for(int i = first[now.to];~i;i = edge[i].next){
                    int to = edge[i].to;
                    LL w = edge[i].w;
                    if(!vis[to]){
                        que.push(Node(to,now.cost + w));
                    }
                }
            }
        }
        return dist[t] == INFF ? -1 : dist[t];
    }
    int main()
    {
            int s, t;
            scanf("%d%d%d",&m,&s,&t);
            n = t + 1;
            init();
            for(int i = 1; i<= m; i++){
               int u, v, w;
               scanf("%d%d%d",&u,&v,&w);
               addEdge(u,v + 1,w);
            }
            for(int i = s + 1; i <= n; i++){
                addEdge(i ,i - 1, 0);
            }
            printf("%lld
    ",dijkstra(s, t+1));
        return 0;
    }
    
  • 相关阅读:
    redis发布订阅
    redis学习笔记(面试题)
    redis安全 (error) NOAUTH Authentication required
    HDU3001 Travelling —— 状压DP(三进制)
    POJ3616 Milking Time —— DP
    POJ3186 Treats for the Cows —— DP
    HDU1074 Doing Homework —— 状压DP
    POJ1661 Help Jimmy —— DP
    HDU1260 Tickets —— DP
    HDU1176 免费馅饼 —— DP
  • 原文地址:https://www.cnblogs.com/qq136155330/p/11328366.html
Copyright © 2011-2022 走看看