• CF960B Minimize the error


    CF960B Minimize the error

    洛谷传送门

    题意翻译

    有两个长度均为 nnn 的序列 a,ba,ba,b,定义 cost(a,b){ m cost}(a,b)cost(a,b) :

    cost(a,b)=∑i=1n(ai−bi)2{ m cost}(a,b)=sum_{i=1}{n}left(a_{i}-b_{i} ight){2} cost(a,b)=i=1∑n(ai−bi)2

    现在必须恰好对 aaa 进行 k1k_1k1 次操作,对 bbb 进行 k2k_2k2 次操作。操作内容是将某一项加一或者减一。求操作后的最小 cost m costcost。

    translated by @皎月半洒花。


    题解:

    一道还不错的贪心。

    发现首先应该考虑差最大的,然后等到把它消成第二大的之后再同时削第二大的...以此类推。

    这个贪心的正确性可以证明,因为平方增长,先消差大的肯定不亏。

    那么上面的消除过程就可以模拟来解决。

    直接优先队列,非常方便。

    需要注意的是,由于操作相同,对于两个数列的操作可以加一起。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define iter(i, a, b) for(int i=(a); i<(b); i++)
    #define rep(i, a) iter(i, 0, a)
    #define rep1(i, a) iter(i, 1, (a)+1)
    #define fi first
    #define se second
    #define pb push_back
    #define ll long long
    #define pii pair<int, int>
    const int MOD = 1e9+7;
    int a[1003], b[1003];
    priority_queue<int, vector<int>> pq;
    signed main() 
    {
        int n, k1, k2; 
        scanf("%lld%lld%lld",&n,&k1,&k2);
        k1 += k2;
        rep(i, n) 
            scanf("%lld",&a[i]);
        rep(i, n) 
        {
            scanf("%lld",&b[i]);
            pq.push(abs(a[i]-b[i]));
        }
        while(k1--) 
        {
            int t = pq.top(); 
            pq.pop();
            if(t == 0) 
                pq.push(1);
            else 
                pq.push(t-1);
        }
        ll ans = 0;
        while(!pq.empty()) 
        {
            ans = ans + 1ll * pq.top() * pq.top();
            pq.pop();
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    jQuery
    数据库的并发操作
    Python之禅
    pymysql模块初见
    数据库之表查询
    实体与实体之间的联系
    数据库初识
    进程池 协程 与I/O模型
    GIL全局解释锁.死锁与递归锁
    进程通信与线程初识
  • 原文地址:https://www.cnblogs.com/fusiwei/p/14012503.html
Copyright © 2020-2023  润新知