960B Minimize the error (思維,貪心)
阿新 • • 發佈:2018-12-13
題目大意:
給你兩個陣列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縮小差距,前三個的差距和不過是,而a4和b4的話
至於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; }