zoukankan      html  css  js  c++  java
  • Codevs 1507 酒厂选址

    1507 酒厂选址
    时间限制: 1 s
    空间限制: 128000 KB
    题目等级 : 黄金 Gold
    传送门
    题目描述 Description
    Abstinence(戒酒)岛的居民们酷爱一种无酒精啤酒。以前这种啤酒都是从波兰进口,但今年居民们想建一个自己的啤酒厂。岛上所有的城市都坐落在海边,并且由一条沿海岸线的环岛高速路连接。酒厂的投资者收集了关于啤酒需求量的信息,即每天各城市消费的啤酒桶数。另外还知道相邻城市之间的距离。每桶啤酒每英里的运费是1元。日运费是将所需要的啤酒从酒厂运到所有城市所必需的运费之和。日运费的多少和酒厂的选址有关。投资者想找到一个合适的城市来修建酒厂,以使得日运费最小。
    请设计一个程序:从文件bre.in 读入城市的数目、相邻两城市间的距离以及每个城市消费的啤酒桶数,计算最小的日运费,将结果写到输出文件bre.out中。
    输入描述 Input Description
    第一行是一个整数n(5 <= n <= 10000) ,表示城市的数目。 城市沿高速路编号,使得相邻的城市的编号也相邻(城市1和n也被认为是相邻)。 以下的n行,每行有两个非负整数。第I+1行的数 zi、di分别是城市I每日的啤酒消费量(桶)和从城市I沿高速路到下一个城市的距离(英里)。高速路的总长不会超过65535 英里。每座城市的日消费量不会超过255桶。
    输出描述 Output Description
    一个整数,表示所需的最小日运费(元)。
    样例输入 Sample Input
    6
    1 2
    2 3
    1 2
    5 2
    1 10
    2 3
    样例输出 Sample Output
    41
    数据范围及提示 Data Size & Hint
    分类标签 Tags
    启发式搜索 模拟 搜索

    /*
    n^2做法.
    一开始搞了一个前缀和和一个后缀和.
    然后跑的时候傻眼了(可能有负的然后各种特判)
    又看了看图
    处理所有权值
    反向跑的时候减去正向跑的权然后取小
    一个前缀和就搞定了.
    ans 可能会特别大(巨坑).
    */
    #include<iostream>
    #include<cstdio>
    #define MAXN 10001
    #define LL long long
    using namespace std;
    LL tot=1e18;
    int n,s[MAXN],t[MAXN],max1;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&t[i],&s[i]);
            max1+=s[i];
            s[i]+=s[i-1];
        }
        for(int k=1;k<=n;k++)
        {
            LL ans=0;
            for(int i=1;i<=n;i++)
            {
                int x=k,y=i;
                if(x>y) swap(x,y);
                ans+=min(s[y-1]-s[x-1],max1-(s[y-1]-s[x-1]))*t
    
    [i];
            }
            tot=min(tot,ans);
        }
        printf("%lld",tot);
        return 0;
    }
    
    /*
    o(n)做法.
    二分答案类似.
    闲的我比着Pascal题解打了一遍.
    枚举酒厂位置,
    可以找到从一个点开始为分界,
    一部分点跑左边,一部分跑右边,
    该点记为mid,
    mid会随着酒厂的右移而右移,具有二分性。
    每次移动时计算答案贡献.
    */
    #include<iostream>
    #include<cstdio>
    #define MAXN 10001 
    using namespace std;
    long long tot,best,ans,ansm,mid,ans1mid,ans2mid;
    long long l,r,min1,s[MAXN],t[MAXN],n,m,tots,tott;
    int main()
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&t[i],&s[i]);
            tots+=s[i];tott+=t[i];
        }
        for(int i=0;i<n;i++)//确定第一次mid的位置.
        {
            m+=s[i];
            min1+=t[i];
            if(m>(tots>>1))
            {
                mid=i;
                m-=s[i];
                l=min1;
                r=tott-min1;
                break;
            }
        }
        for(int i=1;i<=mid;i++)//正向累加.
        {
            tot+=s[i-1];
            ans+=t[i]*tot;
        }
        tot=0;
        for(int i=n-1;i>=mid+1;i--)//反向累加.
        {
            tot+=s[i];
            ans+=t[i]*tot;
        }
        best=ans;//best最优解.
        for(int i=1;i<n;i++)
        {
            m-=s[i-1];
            l-=t[i-1];
            ans1mid=mid;
            while(m<=(tots>>1))//求新的中间位置.
            {
                m+=s[mid];
                mid=(mid+1)%n;
                l+=t[mid];
            }
            l-=t[mid];
            mid=(mid+n-1)%n;
            m-=s[mid];
            r=tott-l;
            ans2mid=mid;
            ansm=m;
            while(ans2mid!=ans1mid)
            {
                ans+=t[ans2mid]*(ansm+s[i-1]-(tots-ansm-s[i-
    
    1]));
                ans2mid=(ans2mid+n-1)%n;
                ansm-=s[ans2mid];
            }
            ans+=(r-l)*s[i-1];
            best=min(best,ans);
            if(i==mid)//特殊情况.
            {
                m=tots;
                l=tott;
                ans=0;
                int tj,j=(i+1)%n;
                tj=s[i];
                while(j!=i)
                {
                    ans+=t[j]*tj;
                    tj+=s[j];
                    j=(j+1)%n;
                }
            }
        }
        printf("%lld",best);
        return 0;
    }
    
  • 相关阅读:
    [Effective C++]条款01:视C++为一个语言联邦
    DOTNET
    simulation
    掩码
    motorsimsrc
    Unprivileged User's Account
    LAN WAN
    calloc malloc realloc
    useradd
    change user ID and group ID
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070816.html
Copyright © 2011-2022 走看看