luogu P2512 [HAOI2008]糖果传递
生活随笔
收集整理的這篇文章主要介紹了
luogu P2512 [HAOI2008]糖果传递
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
Time cost: 35min
環形均分紙牌
我們再回顧一下均分紙牌
1 scanf("%d",&n); 2 for(i = 1; i <= n; i++) 3 { 4 scanf("%d",a + i); 5 sum += a[i]; 6 } 7 double ave = sum / (double)n; 8 int tim = n; 9 sum = 0; 10 for(int i = 1; i <= n; i++) 11 { 12 sum += a[i]; 13 if(sum / (double)i == ave) --tim; 14 }就這么個東西
數組元素減掉平均值之后求前綴和
前綴和為0的時候就說明不用從左邊移牌到右邊 次數-1
這個題雖然問的是最小傳遞數 但是效果一樣?
開始可以考慮枚舉斷開的點
如果在k點斷開 那么就相當于從k開始求前綴和
但是每遍求前綴和復雜度會爆炸O(n^2)
所以可以從1開始求的前綴和推出來后面的就是
n點的前綴和 S[n]-S[k]
1點的前綴和 S[1]+S[n]-S[k]
(就寫這兩個應該就知道了)
這樣就可以O(n^2) 但是還是會爆炸
然后考慮最后的答案就是所有前綴和求和
也就是
考慮數軸上從1到n 每個S[i]位置上有一個點
求最短距離和
是不是看到了種樹問題?
所以就取最中間的點就OK
復雜度O(n)+O(sort)
Code:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define rep(i,a,n) for(int i = a;i <= n;++i) 5 const int N = 1000006; 6 using namespace std; 7 typedef long long ll; 8 ll n,ave,ans; 9 ll a[N],s[N]; 10 int main() { 11 scanf("%lld",&n); 12 rep(i,1,n) scanf("%lld",a+i),ave += a[i]; 13 ave /= n; 14 rep(i,1,n) a[i] -= ave,s[i] = s[i-1] + a[i]; 15 sort(s+1,s+n+1); 16 ave = s[n+1 >> 1]; 17 rep(i,1,n) ans += abs(ave - s[i]); 18 printf("%lld\n",ans); 19 return 0; 20 } View Code?
轉載于:https://www.cnblogs.com/yuyanjiaB/p/9811559.html
總結
以上是生活随笔為你收集整理的luogu P2512 [HAOI2008]糖果传递的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网易云terraform实践
- 下一篇: Jenkins任务失败,发送邮件通知