codeforces 解题报告 1008C. Reorder the Array 贪心

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);
    }
}

猜你喜欢

转载自blog.csdn.net/a912952381/article/details/81040233