• 思维题+贪心——牛客多校第一场C


    /*
    给定一组n维向量 A=(a1/m,a2/m,a3/m ... an/m),
    求另一个n维向量 P=(p1,p2,p3...pn),满足sum{pi}=1,使得ans=sum{(ai/m-pi)^2}最大化
    并求出这个ans
    
    首先将ai放大m倍 A=(a1,a2,a3...an)
    同理 P=(p1,p2,p3...pn),sum{pi}=m
    将ai按照降序排序,可以推出大的数减掉x一定比小的数减掉x更优
        (ai^2-(ai-x)^2)-(aj^2-(aj-x)^2)
        =2*x*ai-x^2-(2*x*xj-x^2)
        =2*x*(ai-aj)>0 
    可以将原问题转化为从a[]数组里减去总和为m的数,使得最后a[]的平方和最小 
    那么我们按照贪心策略进行减法,首先将a1减成a1==a2,然后再将a1a2减成a1==a2==a3,依次类推,直到m不够用 
    
    最后答案就是减法完成后的a[]的平方和,并在除以m*m即可 
    */
    while(~scanf("%d%d", &n, &m)) {
            for(int i = 1; i <= n; ++i) {
                scanf("%d", &a[i]);
            }
            sort(a + 1, a + n + 1, [](int a, int b){return a > b;});
            int idx = n;
            int las = m;
            for(int i = 1; i < n; ++i) {
                if(i * abs(a[i+1] - a[i]) > las) {
                    idx = i;
                    break;
                } else {
                    las -= i * abs(a[i+1] - a[i]);
                }
            }
            LL num1 = 1LL * (idx * a[idx] - las) * (idx * a[idx] - las);
            LL num2 = 1LL * idx * m * m;
            for(int i = idx + 1; i <= n; ++i) {
                num1 += 1LL * a[i] * a[i] * idx;
            }
            LL tmp = __gcd(num1, num2);
            num1 /= tmp, num2 /= tmp;
            if(num2 == 1) printf("%lld
    ", num1);
            else printf("%lld/%lld
    ", num1, num2);
        }
  • 相关阅读:
    算法模板——线性欧拉函数
    2818: Gcd
    1688: [Usaco2005 Open]Disease Manangement 疾病管理
    3314: [Usaco2013 Nov]Crowded Cows
    3450: Tyvj1952 Easy
    1664: [Usaco2006 Open]County Fair Events 参加节日庆祝
    1054: [HAOI2008]移动玩具
    1432: [ZJOI2009]Function
    1121: [POI2008]激光发射器SZK
    1113: [Poi2008]海报PLA
  • 原文地址:https://www.cnblogs.com/zsben991126/p/11272986.html
Copyright © 2020-2023  润新知