zoukankan      html  css  js  c++  java
  • jzoj 3169. 【GDOI2013模拟4】生产汽车

    Description

    题目大意,就是有n个人,m辆车;从第一辆车开始做,做到第m辆车;每辆车要连续地从第一个工人做到第n个工人,第i个工人做第j辆车要a[i] * b[j]分钟。求生产完所有汽车最少需要多少时间。

    Input

    第一行输入两个整数:工人数N(1<=N<=100,000)和汽车数M(1<=M<=100,000)。
    接下来N行描述每一个工人的Ti(1<=Ti<=10,000)。
    接下来M行描述每一台汽车的Fj(1<=Fj<=10,000)。

    Output

    输出一个数表示最少需要的时间。

    Sample Input

    输入1:

    3 3
    2
    1
    1
    2
    1
    1

    输入2:

    3 3
    2
    3
    3
    2
    1
    2

    输入3:

    4 5
    3
    2
    2
    2
    3
    1
    2
    1
    2

    Sample Output

    输出1:

    11

    输出2:

    29

    输出3:

    55

    Data Constraint

    40%的数据满足N,M<=1000。

    Hint

    样例1: 4分钟后,工人1完成1号汽车的工作,他可以立刻开始生产第2台汽车,但如果这样的话将会不满足条件,因为7分钟后,工人2完成2号汽车的工作,此时3号工人还在生产1号汽车,3号工人并不空闲,所以2号汽车在5分钟后开始生产,3号汽车在7分钟后开始生产。3台汽车全部生产完共花费11分钟。

    Solution

    一开始打了个暴力,发现可以斜率优化,推推推。。。
    我们发现,对于第i辆车到第j辆车的过程要max(b[i] * a[j] - b[i+1] * a[j-1])(1<=j<=n)
    设j>k且j比k更大可得斜率式:

    (a[j]-a[k])/(a[j-1]-a[k-1])<b[i+1]/b[i]

    Code

    #include<cstdio>
    #include<algorithm>
    #define N 100010
    #define ll long long
    #define db double
    using namespace std;
    int n,m,b[N],g[N],tot=0;
    ll a[N],sum=0,ans=0;
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    db slope(int x,int y) {return (db)(a[x]-a[y])/(a[x-1]-a[y-1]);}
    
    int main()
    {
    	freopen("car.in","r",stdin);
    //	freopen("car.out","w",stdout); 
    	n=read(),m=read();
    	for (int i=1;i<=n;i++)
    	{
    		a[i]=read()+a[i-1];
    		while (slope(i,g[tot])>slope(g[tot],g[tot-1]) && tot>1) tot--;
    		g[++tot]=i;
    	}
    	for (int i=1;i<=m;i++) b[i]=read();
    	for (int i=1,l,r,mid,s;i<=m;i++)
    	{
    		l=1,r=tot,s=0;
    		while (l<=r)
    		{
    			mid=l+r>>1;
    			if (slope(g[mid],g[mid-1])>(db)b[i+1]/b[i]) s=mid,l=mid+1;
    			else r=mid-1;
    		}
    		ans+=b[i]*a[g[s]]-b[i+1]*a[g[s]-1];
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    POJ 3258 (NOIP2015 D2T1跳石头)
    POJ 3122 二分
    POJ 3104 二分
    POJ 1995 快速幂
    409. Longest Palindrome
    389. Find the Difference
    381. Insert Delete GetRandom O(1)
    380. Insert Delete GetRandom O(1)
    355. Design Twitter
    347. Top K Frequent Elements (sort map)
  • 原文地址:https://www.cnblogs.com/jz929/p/11817537.html
Copyright © 2011-2022 走看看