BZOJ2620 [Usaco2012 Mar]Haybale Restacking

恩,非常好的题。。。至少思路非常巧妙

首先可以得到性质:对于相邻的两堆A & B,A给B然后B再给A是完全没有意义的。。。也就是说只能单向传递

然后我们记下每个点要给(被给)多少堆干草a[i]

同时可以计算出del[i],表示若第i堆只向右传且第n堆不向第1堆运任何干草的情况下i - 1向i传递干草的数量

del[i] = del[i - 1] + a[i - 1](其实就是前缀和)

现在1可以向右移了,设向右移x堆,则ans = Σabs(del[i] - x)

故x = mid(del + 1, del + n + 1)时,ans最小

更加详细见lrj白书P4。。。

 /**************************************************************
Problem: 2620
User: rausen
Language: C++
Result: Accepted
Time:68 ms
Memory:1588 kb
****************************************************************/ #include <cstdio>
#include <algorithm> using namespace std;
typedef long long ll;
const int N = ;
int n;
int a[N], del[N];
ll ans; inline int read(){
int x = , sgn = ;
char ch = getchar();
while (ch < '' || ch > ''){
if (ch == '-') sgn = -;
ch = getchar();
}
while (ch >= '' && ch <= ''){
x = x * + ch - '';
ch = getchar();
}
return sgn * x;
} int main(){
n = read();
int i, m = (n + ) >> ;
for (i = ; i <= n; ++i)
a[i] = read(), a[i] -= read();
for (i = ; i <= n; ++i)
del[i] = a[i - ] + del[i - ];
del[] = a[n] + del[n];
sort(del + , del + n + );
for (i = ; i <= n; ++i)
ans += abs(del[m] - del[i]);
printf("%lld\n", ans);
return ;
}
上一篇:VS code 豆沙绿护眼主题


下一篇:CSS隐藏元素的几种妙法