zoukankan      html  css  js  c++  java
  • [LOJ2347] [JOI 2018 Final] 寒冬暖炉

    Description

    (n) 个客人,分别在 (t_i) 时刻到访,在每一个客人到访时,暖炉必须是打开的。暖炉初始是关闭的,并且最多只能打开 (k) 次。求开着暖炉的最小时间。保证不会有两个客人在同一时间到访。

    Solution

    假设 (t_i) 已经升序排序,那么显然有 (n-1) 个间隔是可以选择的,第 (i) 个间隔的长度是 (t_{i+1}-t_i-1)

    其中,我们最多可以拿掉 (k-1) 个区间,显然我们会拿最大的 (k-1) 个,于是对其排序即可。


    当然,设 (f[i][j]) 表示 ([t_i,t_i+1)) 后,已经用了 (j) 次开启,需要的最短时间,这时 (O(n^2)) 的 dp 也是显然的。


    口胡一个费用流的做法,建立 (S,S',T),每个客人当一对点 (i,i'),按时间排序后依次连线 (i' o i+1),费用为时差。

    (S o S') 限制总流量 (k)(S' o i)(i' o T),费用为 (0)

    (i o i'),费用为 (-M),其中 (M) 是一个很大的负数,通过这样的方式来保证这样的每条边都会被流过。

    没验证过,仅供参考。


    贪心 CODE

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    int n,k,t[N],a[N];
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin>>n>>k;
        for(int i=1;i<=n;i++) cin>>t[i];
        sort(t+1,t+n+1);
        for(int i=1;i<n;i++) a[i]=t[i+1]-t[i]-1;
        sort(a+1,a+n);
        reverse(a+1,a+n);
        int ans=t[n]-t[1]+1;
        for(int i=1;i<k;i++) ans-=a[i];
        cout<<ans<<endl;
    }
    
  • 相关阅读:
    Linux下GCC的使用
    Hadoop c++开发
    如何区别PeekMessage&GetMessage SendMessage&PostMessage
    二叉树的三种遍历方式的循环和递归的实现方式
    各种排序算法的代码
    各种排序算法的总结
    EAX、ECX、EDX、EBX寄存器的作用
    浮点型在内存当中的存储方式
    error LNK2001: 无法解析的外部符号
    线程通信
  • 原文地址:https://www.cnblogs.com/mollnn/p/13672623.html
Copyright © 2011-2022 走看看