zoukankan      html  css  js  c++  java
  • 【洛谷 P5017】 摆渡车(斜率优化)

    题目链接
    算是巩固了一下斜率优化吧。
    (f[i])表示前(i)分钟最少等待时间。
    则有(f[i]=min_{j=0}^{i-m}f[j]+(cnt[i]-cnt[j])*i-(sum[i]-sum[j]))
    其中(cnt[i])(sum[i])分别表示前(i)分钟去等车的学生数量和他们去等车的时刻之和。
    变形一下得(f[j]+sum[j]=i*cnt[j]+i*cnt[i]-sum[i]-f[i])
    维护一个下凸包即可。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAXN = 510;
    const int MAXT = 4000010;
    int n, m, t[MAXN], cnt[MAXT], sum[MAXT], f[MAXT], ans = 2147483647, q[MAXT], head, tail;
    inline double k(int i, int j){
    	return (double)(f[j] + sum[j] - f[i] - sum[i]) / (cnt[i] == cnt[j] ? 1e-9 : cnt[j] - cnt[i]);
    }
    int main(){
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; ++i){
    		scanf("%d", &t[i]);
    		cnt[t[i]]++;
    		sum[t[i]] += t[i]; 
    	}
    	sort(t + 1, t + n + 1);
    	for(int i = 0; i < t[n] + m; ++i)
    		cnt[i] += cnt[i - 1], sum[i] += sum[i - 1];
    	for(int i = 0; i < m; ++i)
    		f[i] = cnt[i] * i - sum[i];
    	for(int i = m; i < t[n] + m; ++i){
    		while(head < tail && k(q[tail - 1], q[tail]) >= k(q[tail], i - m)) --tail;
    		q[++tail] = i - m;
    		while(head < tail && k(q[head], q[head + 1]) <= i) ++head;
    		int j = q[head];
    		f[i] = f[j] + (cnt[i] - cnt[j]) * i - (sum[i] - sum[j]);
    		if(i >= t[n]) ans = min(ans, f[i]);
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    hutool工具
    lombok
    混入
    postMan
    jsr303常用注解
    网页兼容性
    C/C++ 一点笔记(1)
    VS2010 灵活运用快捷操作功能(新手必看)
    HTML中meta作用
    C/C++ 一点笔记(2)
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/11620939.html
Copyright © 2011-2022 走看看