CodeForces - 960B Minimize the error (思维,贪心)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hxxjxw/article/details/82957005

题目大意:

      给你两个数组a,b,你可以对a数组进行k1次操作,每次操作可以选择a数组的一个元素对其+1或-1,对b数组进行k2次操作,每次操作可以选择b数组的一个元素对其+1或-1,最后计算,问E的最小值是多少

题解:

      我们肯定要优先把差距大的给缩小,因为差距大的一平方之后差距会更大,就比如数组元素个数为4,a1和b1,a2和b2,a3和b3的差距都为1,a4和b4差距为3,而我们只能进行k1+k2=3次操作的话,肯定要优先对a4和b4缩小差距,前三个的差距和不过是3*1^{2}=3,而a4和b4的话3^{2}=9

      至于k1,k2必须要全用完的问题,完全可以选择一个数对它加一再减一,所以最后剩下的k1+k2,如果是奇数,就在最后结果+1,偶数的话完全可以两两操作抵消掉

     也可以用优先队列来做

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
struct node
{
    ll a,b,c;
} a[1010];
bool cmp(node a,node b)
{
    return a.c>b.c;
}
int main()
{
    int n,k1,k2;
    cin>>n>>k1>>k2;
    for(int i=0; i<n; i++)
        cin>>a[i].a;
    for(int i=0; i<n; i++)
    {
        cin>>a[i].b;
        a[i].c=abs(a[i].b-a[i].a);
    }
    sort(a,a+n,cmp);
    bool flag=1;
    while(k1 && flag)
    {
        flag=0;
        if(a[0].c>0)
        {
            a[0].c--;
            k1--;
            flag=1;
        }
        sort(a,a+n,cmp);
    }
    flag=1;
    while(k2 && flag)
    {
        flag=0;
        if(a[0].c>0)
        {
            a[0].c--;
            k2--;
            flag=1;
        }
        sort(a,a+n,cmp);
    }
    ll ans(0);
    for(int i=0; i<n; i++)
        ans+=a[i].c*a[i].c;
    ans+=((k1+k2)&1);
    cout<<ans<<"\n";
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hxxjxw/article/details/82957005