• 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;
    }
    
    转载需注明出处。
  • 相关阅读:
    NHbiernate 配置
    NHibernate开发入门
    Thread 线程简单例子
    C#中委托和事件
    DataGridView 去掉多余的列
    ASP.NET C# 有程序集加不了解决办法
    oracle“记录被另一个用户锁住”
    Android 控件属性
    Android 入门
    MVC 视频笔记
  • 原文地址:https://www.cnblogs.com/jz929/p/11817537.html
Copyright © 2020-2023  润新知