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;
}