http://codeforces.com/contest/1008/problem/C
解題思路:
1.給出一個序列,你可以任意變換數字的位置,最終使得所有位置比原位置的數大於的總和最大
2.先對數組進行小到大排序
3.計算所有相同值的個數
4.最左邊的一組數都能被它右邊的任意值覆蓋而達到要求,當然這個覆蓋的數量是最左邊組和次左邊組的個數的較小值
5.然後用這兩組合併成爲新的一組可以被覆蓋的序列,選擇兩組的較大值,因爲覆蓋過後的和 未覆蓋的或者未被覆蓋的 都可以被它們右邊下一組的值覆蓋
6.重複4,5操作,最後退出循環後再進行一次計算覆蓋數量即可
7.注意出現序列全部的值都相同的情況
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] w = new int[100010];
for(int i = 0;i < n;i++) {
w[i] = sc.nextInt();
}
Arrays.sort(w,0,n);
long ans = 0,sum = 1;
int i;
for(i = 1;i < n;i++) { //記錄最小值的個數
if(w[i] == w[i - 1])
sum++;
else break;
}
boolean tag = true;
if(i == n) //所有數字都相等,答案就是0
tag = false;
long sum2 = 1;
for(i = i + 1;i < n;i++) {
if(w[i] == w[i - 1]) //計算下一組相同值的個數
sum2++;
else {
ans += Math.min(sum,sum2); //總數加上兩組個數的較小值
sum = Math.max(sum,sum2); //維護當前可以被覆蓋的數量
sum2 = 1; //重新計算
}
}
if(tag == true)
ans += Math.min(sum,sum2);
System.out.println(ans);
}
}