「 Luogu P3137 」X 「 USACO16FEB 」 圓形谷倉
阿新 • • 發佈:2018-09-11
序列 %d als tor priority int cstring true 移動
# 題目大意
管理大大給修下 $\text{Markdown}$ 吧,嚴重影響做題體驗啊。
這道題的意思很簡單就是給你一個長度是 $n$ 的環,這個環上不均勻的分布著 $n$ 頭奶牛。一頭奶牛移動要花費的代價是距離的平方,現在讓你求出使得每個點上都有一頭奶牛需要花費的最小代價,註意,奶牛只能順時針移動。
# 解題思路
首先斷環成鏈這個大家應該都知道,就是將原序列 copy 一份放到後面去。
然後考慮如果一頭奶牛在移動的過程中沒有經過其他奶牛,那這一定是最優的方案。還有就是如果一個點有奶牛,那將奶牛運到它順時針防線上離它連續一段 $0$ 的最後一個 $0$。
枚舉初始位置,從初始位置開始如果遇到有牛的地方,就將這個位置放到優先隊列 (小根堆) 裏,在往後掃的過程中將其慢慢移動過來。
直觀的說就是下面這個式子:
$$a^2+b^2<(a+b)^2$$
# 附上代碼
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; int n, a[2003], cnt, ans = 1e9; priority_queue <int, vector<int>, greater<int> > Q;bool flag = true; int main() { scanf("%d", &n); for(int i=1; i<=n; i++) { scanf("%d", &a[i]); a[i+n] = a[i]; } static int tmp; for(int i=1; i<=n; i++) { cnt = 0, flag = true; for(int j=i; j<=i+n-1; j++) { if(Q.empty() && a[j] == 0) {flag = false; break;} tmp = a[j]; while (tmp--) Q.push(j); tmp = Q.top(), Q.pop(); cnt += (tmp-j) * (tmp-j); } if(!flag) continue; ans = min(ans, cnt); } printf("%d", ans); }
「 Luogu P3137 」X 「 USACO16FEB 」 圓形谷倉