zoukankan      html  css  js  c++  java
  • SPOJ 1873 Accumulate Cargo

    SPOJ_1873

        这个题目的子问题实际上是SGU_114一类的题目(http://www.cnblogs.com/staginner/archive/2012/01/11/2319989.html)。

        首先可以把题意转化为每次可以将一个或一堆连在一起的方块向左移一个位置或者向右移一个位置,最后的代价就是各个方块移动的长度之和。可以证明,最优解中,每个方块应该都是向着某个点移动的,不会说先左移移再右移移之类的,那样一定不如一开始就向着一个方向移划得来。

        这样根据移动的方向不同,那么这个环就可以等价成一条链,只不过现在还不明白从哪里断开。

        不过不妨先加假设成现在已经断成了一条链,那么这些方块该向着那个点移动呢?细想之后就会发现和SGU_114是一样的,向着中间的那个方块移动就行了。这样我们可以O(1)的时间求出这条链上方块聚集到一起的最小代价。

        既然不知道从哪里断开,不妨就枚举断开的位置,或者更方便一点,枚举向着哪个方块移动,然后左边(N-1)/2个方块向右移,右边N/2个方块向左移就行了,这样整体就是O(N)的复杂度。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAXD 200010
    using namespace std;
    int N, L, a[MAXD];
    long long A[MAXD], AA[MAXD], B[MAXD], BB[MAXD];
    void init()
    {
        int i, j, k;
        a[0] = -1;
        for(i = 1; i <= N; i ++)
            scanf("%d", &a[i]);
        sort(a + 1, a + 1 + N);
        for(i = N + 1; i <= (N << 1); i ++)
            a[i] = a[i - N] + L;
        a[N << 1 | 1] = L << 1;
        A[0] = 0;
        for(i = 1; i <= (N << 1); i ++)
            A[i] = A[i - 1] + a[i] - a[i - 1] - 1;
        B[N << 1 | 1] = 0;
        for(i = N << 1; i > 0; i --)
            B[i] = B[i + 1] + a[i + 1] - a[i] - 1;
        AA[0] = 0;
        for(i = 1; i <= (N << 1); i ++)
            AA[i] = AA[i - 1] + A[i];
        BB[N << 1 | 1] = 0;
        for(i = N << 1; i > 0; i --)
            BB[i] = BB[i + 1] + B[i];
    }
    long long Min(long long x, long long y)
    {
        return x < y ? x : y;
    }
    void solve()
    {
        int i, j, k, ln = N - 1 >> 1, rn = N >> 1, x, y;
        long long ans = 1ll << 62, tl, tr;
        for(i = 1; i <= N; i ++)
        {
            tl = BB[i + N - ln] - BB[i + N] - ln * B[i + N];
            tr = AA[i + rn] - AA[i] - rn * A[i];
            ans = Min(ans, tl + tr);
        }
        printf("%lld\n", ans);
    }
    int main()
    {
        for(;;)
        {
            scanf("%lld%lld", &N, &L);
            if(N == 0 && L == 0)
                break;
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    P1158 导弹拦截
    麦基数(p1045)
    Django之路由层
    web应用与http协议
    Django之简介
    Mysql之表的查询
    Mysql之完整性约束
    Mysql之常用操作
    Mysql之数据类型
    Mysql之数据库简介
  • 原文地址:https://www.cnblogs.com/staginner/p/2596635.html
Copyright © 2011-2022 走看看