Whu 1603——Minimum Sum——————【单个元素贡献、滑窗】
Problem 1603 - Minimum Sum
Time Limit: 2000MS Memory Limit: 65536KB
Total Submit: 623 Accepted: 178 Special Judge: No
Total Submit: 623 Accepted: 178 Special Judge: No
Description
There are n numbers A[1] , A[2] .... A[n], you can select m numbers of it A[B[1]] , A[B[2]] ... A[B[m]] ( 1 <= B[1] < B[2] .... B[m] <= n ) such that Sum as small as possible.
Sum is sum of abs( A[B[i]]-A[B[j]] ) when 1 <= i < j <= m.
Input
There are multiple test cases.
First line of each case contains two integers n and m.( 1 <= m <= n <= 100000 )
Next line contains n integers A[1] , A[2] .... A[n].( 0 <= A[i] <= 100000 )
It's guaranteed that the sum of n is not larger than 1000000.
First line of each case contains two integers n and m.( 1 <= m <= n <= 100000 )
Next line contains n integers A[1] , A[2] .... A[n].( 0 <= A[i] <= 100000 )
It's guaranteed that the sum of n is not larger than 1000000.
Output
For each test case, output minimum Sum in a line.
Sample Input
4 2
5 1 7 10
5 3
1 8 6 3 10
5 1 7 10
5 3
1 8 6 3 10
Sample Output
2
8
8
题目大意:让你从n个数中挑出m个,求这m个数中任意两个元素差的绝对值,然后求和。问你最小的绝对值和为多少。
解题思路:首先可以确定的是,如果挑出的m个数越平稳,那么绝对值和最小。(当时没考虑到只要排序后,就是最平稳的了)所以问题转化成,如何求排序后的n个元素的序列中m个相连元素差的绝对值和最小。滑动窗口(计算机网络中的名词),当加入a[i]时,a[i-m]就要退出来,始终保证只有m个元素。那么只需要考虑加入和退出元素产生的贡献。
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<iostream>
using namespace std;
const int maxn = 1e5+200;
typedef long long LL;
int a[maxn], sum[maxn];
int main(){
int n, m;
while(scanf("%d%d",&n,&m)!=EOF){
for(int i = 1; i <= n; i++){
scanf("%d",&a[i]);
}
sort(a+1,a+1+n);
for(int i = 1; i <= n; i++){
sum[i] = sum[i-1]+a[i];
}
int ans = 0, tmp;
for(int i = 2; i <= m; i++){
ans += a[i]*(i-1) - (sum[i-1] - sum[0]);
}
tmp = ans;
if(n == m){
printf("%d\n",ans); continue;
}
for(int i = m+1; i <= n; i++){
tmp = tmp + a[i]*(m-1) - (sum[i-1] - sum[i-m]) - ((sum[i-1]-sum[i-m]) - a[i-m]*(m-1));
ans = min(ans,tmp);
}
printf("%d\n",ans);
}
return 0;
}
学学学 练练练 刷刷刷

浙公网安备 33010602011771号