Java algorithm water extraction problem

Question description

N people want to fetch water. There are M faucets. The time required for the i-th person to fetch water is Ti. Please arrange a reasonable plan to make the sum of everyone's waiting time as small as possible.

Input
Input description:
  Two positive integers N M in the first line and N positive integers Ti in the next line.
  N,M<=1000, Ti<=1000
Input example:
7 3
3 6 1 4 2 5 7

output

Output description:
  The sum of the minimum waiting times. (No need to output specific arrangements)
Output sample:
11

HINT: Time limit: 1.0s Memory limit: 512.0MB
  An optimal water extraction plan is to allocate N people to M in order of Ti from small to large. The faucet draws water.
  For example, in the example, Ti is sorted from small to large as 1, 2, 3, 4, 5, 6, 7. If they are assigned to 3 faucets in turn, then go to the faucet to get water. The numbers are 1, 4, 7; those who go to the second faucet to fetch water are 2,5; those who go to the third faucet to fetch water are 3,6.
  The total waiting time of the person who fetched water from the first faucet = 0 + 1 + (1 + 4) = 6
  The total waiting time of the person who fetched water from the second faucet Waiting time = 0 + 2 = 2
  The total waiting time of the third person to fetch water = 0 + 3 = 3
  So the total waiting time = 6 + 2 + 3 = 11

Problem-solving ideas

After sorting according to the time of fetching water, add them into a two-dimensional array of n columns from small to large. Just see how many rounds it takes. Then just add up the waiting time between each round.

code

import java.util.Arrays;
import java.util.Scanner;


public class Main {
    
    

        public static void main(String[] args) {
    
    
            Scanner sc = new Scanner(System.in);
            int a = sc.nextInt();
            int b = sc.nextInt();
            int[] m =new int[a];  //储存用户输入的一组数据
            for (int i = 0; i <a; i++) {
    
    
                m[i]=sc.nextInt();
            }
            Arrays.sort(m); //从小到大排序
            int row = (a/b)+1;  //定义二维数组的行数
            int[][] n =new int[row][b]; //定义一个二维数组来对用户输入的数据进行按顺序分配成row行b列
            int s = 0;  //定义变量用来计数,
            for (int i = 0; i <row; i++) {
    
    
                for (int j = 0; j <b; j++) {
    
    
                    if (s<a) {
    
     //防止越界
                        n[i][j]=m[s];
                        s++;
                    }
                }
            }
            int sum = 0; //用来存储最短的时间总和
            for (int t = 1; t <a/b; t++) {
    
      //第一层循环用来判断循环次数
                for (int i = 0; i <t; i++) {
    
    
                    for (int j = 0; j <b; j++) {
    
    
                        sum+=n[i][j];  //对接水的时间进行累加
                    }
                }
            }
            for (int i = 0; i <row-1; i++) {
    
    
                for (int j = 0; j <a%b; j++) {
    
    
                    sum+=n[i][j];  //因为后面的人数等的时间应该要把前面所有人等的时间全部加起来,所以我们只要在之前的sum基础上继续累加就可以了
                }
            }
            System.out.println(sum);  //最后输出总时间
        }
}

Guess you like

Origin blog.csdn.net/joreng/article/details/123853711