POJ 2231 Moo Volume(递推、前缀和)

mac2022-06-30  161

 

题外话:POJ 2231 Moo Volume 题意:解题过程:AC代码:

 

题外话:

emm……第三套题好像综合了其他OJ的题目蛤,那么我就把题目分开了发了蛤蛤……

POJ 2231 Moo Volume

题目传送门

题意:

你有一个牛庄,牛庄中总共有n头牛,在晚上,每两头牛都会进行交谈,而交谈的声音的音量就是这两头牛的距离,给出你这n头牛各自的位置,让你求在晚上这些牛发出的总音量。

解题过程:

看了题目发现n有100000,所以暴力是肯定过不了的,那么我们就可以考虑另一种类似公式递推的方法,我们先对所有牛按照位置进行排序,然后假设F[i]表示第i头牛与其他牛交谈发出的总音量,然后对于第i+1头牛,我们设一个d值,代表第i头牛与第i+1头牛之间的距离,那么对于第i+1头牛之前的牛j,与第i+1头牛交谈产生的音量值就是第i头牛与第j头牛交谈的音量+d,同样,对于第i+1头牛之后的牛j,与第i+1头牛交谈产生的音量值就是第i头牛与第j头牛交谈的音量-d,所以我们可以得出递推式F[i+1]=F[i]+d*(i-1)+d*(n-i+1),这样O(n)递推下去就行了,最后把音量值加起来就是所求的答案了。

AC代码:

#include <cstdio> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <set> #include <map> #include <list> #include <vector> #include <cstdlib> #include <cstring> using namespace std; typedef long long ll; const int maxn=100005; int n; ll a[maxn]; ll f[maxn]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); } sort(a+1,a+1+n); for(int i=1;i<=n;i++) { f[1]+=a[i]-a[1]; } ll ans=f[1]; for(int i=2;i<=n;i++) { ll d=a[i]-a[i-1]; f[i]=f[i-1]+d*(i-1)-d*(n-i+1); ans+=f[i]; } printf("%lld\n",ans); return 0; }

本人蒟蒻OIer一枚,欢迎加QQ:840776708一起学习蛤。

转载于:https://www.cnblogs.com/Apocrypha/p/9433672.html

最新回复(0)