UVA12904 Load Balancing(中途相遇法)

虽然这题可以用暴力n^3过,但是还有有种n^2的方法的,枚举b,对于b,分别枚举a和c,得到对于这个b的最优解,然后从所以b中选一个最优的。

要保证字典序最小,只要从小往大枚举就好了

感谢moonflyer

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>

using namespace std;

const int maxn = 160+5;
int cnt[maxn];
int sum[maxn];

int main()
{
    //freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    int Cas = 0;
    while(T--){
        int n;
        memset(cnt,0,sizeof(cnt));
        scanf("%d",&n);
        for(int i = 0; i < n; i++){
            int t;
            scanf("%d",&t);
            cnt[t]++;
        }
        memcpy(sum,cnt,sizeof(cnt));
        for(int i = 1; i <= 160; i++)
            sum[i] += sum[i-1];
        double ave = n/4.0;
        double bdif = 1e30;
        int besta = 0,bestb = 1,bestc = 2;
        for(int b = 1; b < 160; b++){
            double dif1 = fabs(sum[0]-ave) + fabs(sum[b]-sum[0]-ave);
            int pba = 0;
            for(int a = 1; a < b; a++){
                double ndif = fabs(sum[a]-ave)+fabs(sum[b]-sum[a]-ave);
                if(ndif<dif1){
                    dif1 = ndif; pba = a;
                }
            }
            int pbc = b+1;
            double dif2 = fabs(sum[b+1]-sum[b]) + fabs(sum[160]-sum[b+1]);
            for(int c = b+2; c<=160; c++){
                double ndif = fabs(sum[c]-sum[b]-ave)+fabs(sum[160]-sum[c]-ave);
                if(ndif < dif2){
                    dif2 = ndif; pbc = c;
                }
            }
            if(dif1+dif2<bdif){
                besta = pba; bestb = b; bestc = pbc;
                bdif = dif1+dif2;
            }
        }
        printf("Case %d: %d %d %d
",++Cas,besta,bestb,bestc);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/4655919.html