bzoj1045 糖果传递
生活随笔
收集整理的這篇文章主要介紹了
bzoj1045 糖果传递
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Description
有n個(gè)小朋友坐成一圈,每人有ai個(gè)糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞一個(gè)糖果代價(jià)為1。
Input
第一行一個(gè)正整數(shù)nn<=1'000'000,表示小朋友的個(gè)數(shù). 接下來n行,每行一個(gè)整數(shù)ai,表示第i個(gè)小朋友得到的糖果的顆數(shù).Output
求使所有人獲得均等糖果的最小代價(jià)。
Sample Input
41
2
5
4
Sample Output
4 這道題讓我想到了白書上面的相似的一道題:UVA11300 Spreading the Wealth
A Communist regime is trying to redistribute wealth in a village. They have have decided to sit everyone around a circular table. First, everyone has converted all of their properties to coins of equal value, such that the total number of coins is divisible by the number of people in the village. Finally, each person gives a number of coins to the person on his right and a number coins to the person on his left, such that in the end, everyone has the same number of coins. Given the number of coins of each person, compute the minimum number of coins that must be transferred using this method so that everyone has the same number of coins.Input
There is a number of inputs. Each input begins with n (n < 1000001), the number of people in the village. n lines follow, giving the number of coins of each person in the village, in counterclockwise order around the table. The total number of coins will fit inside an unsigned 64 bit integer.Output
For each input, output the minimum number of coins that must be transferred on a single line.Sample Input
3 100 100 100 4 1 2 5 4Sample Output
0 4 題意:n個(gè)人圍成一圈,每個(gè)人都有一些硬幣,,每個(gè)人只能給左右相鄰的人硬幣,問最少交換幾個(gè)硬幣,使每個(gè)人硬幣一樣多。 我第一反應(yīng):費(fèi)用流。第二反應(yīng):費(fèi)用流。第三反應(yīng):費(fèi)用流。 然后看uva11300題解: 首先,最終每個(gè)人金幣數(shù)量可以計(jì)算出來,我們用M表示每個(gè)人最后擁有的金幣數(shù)。 我們對(duì)于第i個(gè)人可以看作他給了他左邊的人xi個(gè)金幣(負(fù)數(shù)表示反向傳遞),他右邊的人給了他xi+1個(gè)金幣,假設(shè)他一開始擁有的金幣數(shù)量為Ai,那么有Ai-xi+xi+1=M。 如果我們繼續(xù)列下去就會(huì)變成這樣: A1-x1+x2=M -> x2=M-A1+x1?-> ?令C1=A1-M -> x2=x1-C1 A2-x2+x3=M -> x3=M-A2+x2=2*M-A1-A2+x1 -> ?令C2=A1+A2-2*M -> x3=x1-C2 A3-x3+x4=M -> x4=M-A3+x3=3*M-A1-A2-A3+x1?-> ?令C3=A1+A2+A3-3*M?-> x4=x1-C3 ....... 那么我們就會(huì)得到n個(gè)等式,但是我們發(fā)現(xiàn)我們可以用這n個(gè)等式中的任意n-1個(gè)去變換得到最后剩下那個(gè)等式。 因?yàn)槲覀冎?$\sum A_i =M \times n $ ,那么最后一個(gè)等式Cn=0,就是x1=x1。 也就是說,最后那個(gè)等式是沒有用的,我們只會(huì)用到n-1個(gè)等式。那么這n-1個(gè)等式可以用來做什么呢,我們?cè)鯓硬拍芮蟮?$ \sum abs(x_i) $ 最小值呢? $ \sum abs( x_i ) = abs( x_1 )+abs( x_2 )+abs( x_3 )+......+abs( x_n )=abs( x_1 ) +abs(x_1-C_1) +abs(x_1- C_2)+ ......+abs(x_1-C_{n-1})$ 由于Ci是可以直接計(jì)算出來的,可以當(dāng)作常數(shù),所以說這個(gè)等式相當(dāng)于是求一個(gè)最優(yōu)的x1,使得數(shù)軸上x1到Ci距離和最小,而這個(gè)距離和就是我們所求的答案。 最后問題轉(zhuǎn)化成求數(shù)軸上一個(gè)點(diǎn)到所有已知的點(diǎn)最小距離,相信在小學(xué)(或是初中)數(shù)學(xué)老師都講過,這樣的點(diǎn)就是中位數(shù)啦。 然后就直接算出C,然后算中位數(shù)與其他的所有的點(diǎn)的距離。 bzoj1045 代碼: //Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=1e6+10; long long n,tot,ans,c,A[maxn],C[maxn];long long aa;char cc; long long read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa; }int main() {n=read();for(int i=1;i<=n;++i) A[i]=read(),tot+=A[i];tot/=n;for(int i=1;i<n;++i) C[i]=A[i]-tot+C[i-1];sort(C+1,C+n+1);//還有一個(gè)C[i]為0的 for(int i=1;i<=n;++i) ans+=abs(C[i]-C[(n+1)>>1]);printf("%lld",ans);return 0; }
轉(zhuǎn)載于:https://www.cnblogs.com/Serene-shixinyi/p/7594077.html
總結(jié)
以上是生活随笔為你收集整理的bzoj1045 糖果传递的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: segnet 编译与测试
- 下一篇: 通过conda或者pip安装包时出现Th