目录
(1)由上面的图片可得,count数组储存arr元素被加的次数
(3)求和:为了方便计算,将arr与count分别排序后再计算
纪录一下昨天考场上“才思敏捷”的思路
试题 G: 重新排序
【问题描述】
给定一个数组 A 和一些查询 L**i, R**i,求数组中第 L**i 至第 R**i 个元素之和。 小蓝觉得这个问题很无聊,于是他想重新排列一下数组,使得最终每个查询结果的和尽可能地大。小蓝想知道相比原数组,所有查询结果的总和最多可以增加多少?
【输入格式】
输入第一行包含一个整数 n。
第二行包含 n 个整数 A1, A2, · · · , A**n,相邻两个整数之间用一个空格分隔。
第三行包含一个整数 m 表示查询的数目。
接下来 m 行,每行包含两个整数 L**i、R**i ,相邻两个整数之间用一个空格分隔。
【输出格式】
输出一行包含一个整数表示答案。
【样例输入】
5
1 2 3 4 5
2
1 3
2 5
【样例输出】
4
【样例说明】
原来的和为 6 + 14 = 20,重新排列为 (1, 4, 5, 2, 3) 后和为 10 + 14 = 24,增
加了 4。
【评测用例规模与约定】
对于 30% 的评测用例,n, m ≤ 50 ;
对于 50% 的评测用例,n, m ≤ 500 ;
对于 70% 的评测用例,n, m ≤ 5000 ;
对于所有评测用例,1 ≤ n, m ≤ 10^5,1 ≤ A**i ≤ 10^6,1 ≤ L**i ≤ R**i ≤ 10^6 。
思路:
1、如何求原数组的和?
(1)count数组用来记录数组元素被加的次数
(2)求和
2、如何给数组arr排序使得结果最大?
(1)由上面的图片可得,count数组储存arr元素被加的次数
(2)让arr中最大的元素被加的次数最多
(3)求和:为了方便计算,将arr与count分别排序后再计算
代码(40′):
import java.util.Arrays;
import java.util.Scanner;
public class Main_G {
/**
*给定一个数组 A 和一些查询 L**i, R**i,求数组中第 L**i 至第 R**i 个元素之和。
* 小蓝觉得这个问题很无聊,于是他想重新排列一下数组,使得最终每个查询结果的和尽可能地大。
* 小蓝想知道相比原数组,所有查询结果的总和最多可以增加多少?
*/
static int[]arr;
static int[][]arr_m;
static int[]count;
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
//输入
int N=scan.nextInt();
arr=new int[N];
for (int i = 0; i < N; i++) {
arr[i]=scan.nextInt();
}
int M=scan.nextInt();
arr_m=new int[M][2];
for (int i = 0; i < M; i++) {
arr_m[i][0]=scan.nextInt();
arr_m[i][1]=scan.nextInt();
}
//count纪录元素被加次数
count=new int[N];
for (int i = 0; i < M; i++) {
for (int j = arr_m[i][0]-1; j <=arr_m[i][1]-1 ; j++) {
count[j]++;
}
}
//排序前的和
int sum1=SUM(arr,count);
//对arr与count分别进行排序
Arrays.sort(arr);
Arrays.sort(count);
//排序后的和
int sum2=SUM(arr,count);
//输出结果
System.out.println(sum2-sum1);
}
public static int SUM(int []arr, int[] count){
int sum=0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i]*count[i];
}
return sum;
}
}
代码:结合差分数组 (90')
package lanqiaobei_;
import java.util.Arrays;
import java.util.Scanner;
public class chongxinpaixu {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N=scanner.nextInt();
long arr[]=new long[N];
long count[]=new long[N];
long difference[]=new long[N+1];
for (int i = 0; i < N; i++) {
arr[i]=scanner.nextInt();
}
int M=scanner.nextInt();
int L;
int R;
for (int i = 1; i <=M ; i++) {
L=scanner.nextInt();
R=scanner.nextInt();
difference[L-1]++;
difference[R]--;
}
count[0]=difference[0];
for (int i = 1; i <count.length; i++) {
count[i]=count[i-1]+difference[i];
}
//排序前的和
long sum1=arrsum(arr,count);
//排序·
Arrays.sort(arr);
Arrays.sort(count);
long sum2=arrsum(arr,count);
System.out.println(sum2-sum1);
}
public static long arrsum(long arr[],long count[]){
long sum=0;
for (int i = 0; i < arr.length; i++) {
sum=sum+arr[i]*count[i];
}
return sum;
}
}