洛谷P1368 均分紙牌(加強版)
阿新 • • 發佈:2017-08-25
hellip 問題 只有一個 一行 return ont -1 col 個數
P1368 均分紙牌(加強版)
題目描述
有 N 堆紙牌,編號分別為 1,2,…, N。每堆上有若幹張,紙牌總數必為 N 的倍數。可以在任一堆上取1張紙牌,然後移動。
移牌規則為:在編號為 1 堆上取的紙牌,能移到編號為 2和N 的堆上;在編號為 N 的堆上取的紙牌,能移到編號為 N-1和1 的堆上;其他堆上取的紙牌,可以移到相鄰左邊或右邊的堆上。
現在要求找出一種移動方法,使每堆上紙牌數都一樣多且牌的移動次數盡量少。
輸入輸出格式
輸入格式:
第一行一個整數n
第二行為n個空格分開的正整數,為n堆紙牌的牌數。
輸出格式:
只有一個數,為最少的移動次數。
輸入輸出樣例
輸入樣例#1:4 1 2 5 4輸出樣例#1:
4
說明
對樣例的說明:
①第4堆移動1張牌至第1堆
②第3堆移動1張牌至第2堆
③第3堆移動1張牌至第2堆
④第2堆移動1張牌至第1堆
此時移動次數為4最小
【數據範圍】
對於40%的數據,n<=10000
對於100%的數據,n<=1000000,所有紙牌數總和在2147483647內
/* 設平均數為xba 不妨設a1給了an x1 張紙牌(k可正可負),a2給了a1 x2張紙牌, a3給了a2 x3 張紙牌……an給了a(n - 1) xn張紙牌,不難發現以下方程: xba = a1 - x1 + x2 xba = a2 - x2 + x3 xba = a3 - x3 + x4 xba = a4 - x4 + x5 ...... xba = a(n - 1) - x(n - 1) + xn xba = an - xn + x1 我們考慮最終結果,應該是 |x1| + |x2| + |x3| + .... + |xn| 換元法,得到 ans = |x1| + |xba - a1 + x1| + |2xba -a1 - a2 + x1| + |3xba -a1 - a2 - a3 + x1| + ..... + |(n - 1)xba - Σai,i <= n - 1|轉換為一次函數帶絕對值的最值問題 數形結合思想,看做是數軸上點的距離。 中位數時距離和最小。*/ #include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define maxn 1000010 #define INF 0x3f3f3f3f long long a[maxn],sum,f[maxn],xba,n,k,ans; int main(){ scanf("%d",&n); for(long long i=1;i<=n;i++){ cin>>a[i]; sum+=a[i]; } xba=sum/n; f[1]=0; for(long long i=2;i<=n;i++) f[i]=f[i-1]+xba-a[i-1]; sort(f+1,f+n+1); k=f[n/2+1]; for(long long i=1;i<=n;i++) ans+=abs(k-f[i]); cout<<ans; return 0; }
洛谷P1368 均分紙牌(加強版)