2 条题解
-
0
设最优的方案中,位置1往位置n送k捆草,则: a[2]要往a[1]移s[1]捆,s[1]=b[1]-(a[1]-k)=b[1]-a[1]+k; a[3]要往a[2]移s[2]捆,s[2]=b[2]-(a[2]-(b[1]-a[1]+k))=(b[2]-a[2]) + (b[1]-a[1]) +k个, 以此类推...... a[i+1]要往a[i]移s[i]捆,s[i]=Σ(b[j]-a[j])(1<=j<i)+ k ; 设 c[i]=(b[1]-a[1])+(b[2]-a[2])+.....+(b[i]-a[i]) 故: s[1]=c[1]+k s[2]=c[2]+k ... s[i]=c[i]+k 注 s[i]和 k 的值可正可负,才能表达 某个位置可向左右送草。 答案为:Σ|s[i]|=Σ|c[i]+k| c[i]是确定的,k不是确定的,如何设计k的值让Σ|c[i]+k|最小? 可以将|c[i]+k|转化为|c[i]-(-k)|,则答案可以看成一条数轴上,值为c[i](1<=i<=n)的点到(-k)的距离。 所以:当k为其中位数时,答案最小
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int a[N],b[N],c[N]; int main() { int n;scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]); c[0]=0; for(int i=1;i<=n;i++) { c[i]=c[i-1]+b[i]-a[i]; } sort(c+1,c+n+1); int k=c[(n+1)/2]; long long ans=0; for(int i=1;i<=n;i++) ans+=abs(c[i]-k); printf("%lld\n",ans); return 0; } -
0
/* 设最优的方案中,位置1往位置n送k捆草,则: a[2]要往a[1]移s[1]捆,s[1]=b[1]-(a[1]-k)=b[1]-a[1]+k; a[3]要往a[2]移s[2]捆,s[2]=b[2]-(a[2]-(b[1]-a[1]+k))=(b[2]-a[2]) + (b[1]-a[1]) +k个, 以此类推...... a[i+1]要往a[i]移s[i]捆,s[i]=Σ(b[j]-a[j])(1<=j<i)+ k ; 设 c[i]=(b[1]-a[1])+(b[2]-a[2])+.....+(b[i]-a[i]) 故: s[1]=c[1]+k s[2]=c[2]+k ... s[i]=c[i]+k 注 s[i]和 k 的值可正可负,才能表达 某个位置可向左右送草。 答案为:Σ|s[i]|=Σ|c[i]+k| c[i]是确定的,k不是确定的,如何设计k的值让Σ|c[i]+k|最小? 可以将|c[i]+k|转化为|c[i]-(-k)|,则答案可以看成一条数轴上,值为c[i](1<=i<=n)的点到(-k)的距离。 所以:当k为其中位数时,答案最小。 */ #include<bits/stdc++.h> using namespace std; const int N=1e5+10; int a[N],b[N],c[N]; int main() { int n;scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]); c[0]=0; for(int i=1;i<=n;i++) { c[i]=c[i-1]+b[i]-a[i]; } sort(c+1,c+n+1); int k=c[(n+1)/2]; long long ans=0; for(int i=1;i<=n;i++) ans+=abs(c[i]-k); printf("%lld\n",ans); return 0; }
- 1
信息
- ID
- 2615
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- 递交数
- 67
- 已通过
- 33
- 上传者