FJUT2019暑假第二次周赛 A题

Posted qq136155330

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n";
    
    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\n",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\n",dijkstra(s, t+1));
    return 0;

以上是关于FJUT2019暑假第二次周赛 A题的主要内容,如果未能解决你的问题,请参考以下文章

SWPUACM第二次周赛

AcWing第2次周赛——第二题(3627. 最大差值 )贪心策略

2019下学期第二次个人周赛—A题

第三次周赛 总结:是的,我在进步中。。。

FJUTOJ-周赛2016-11-25

FJUTOJ-周赛2016-12-16