-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathE. Yet Another Division Into Teams
173 lines (130 loc) · 5.33 KB
/
E. Yet Another Division Into Teams
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
Problem :
There are n students at your university. The programming skill of the i-th student is ai. As a coach, you want to divide them into teams to prepare them for the upcoming ICPC finals. Just imagine how good this university is if it has 2⋅105 students ready for the finals!
Each team should consist of at least three students. Each student should belong to exactly one team. The diversity of a team is the difference between the maximum programming skill of some student that belongs to this team and the minimum programming skill of some student that belongs to this team (in other words, if the team consists of k students with programming skills a[i1],a[i2],…,a[ik], then the diversity of this team is maxj=1ka[ij]−minj=1ka[ij]).
The total diversity is the sum of diversities of all teams formed.
Your task is to minimize the total diversity of the division of students and find the optimal way to divide the students.
Input
The first line of the input contains one integer n (3≤n≤2⋅105) — the number of students.
The second line of the input contains n integers a1,a2,…,an (1≤ai≤109), where ai is the programming skill of the i-th student.
Output
In the first line print two integers res and k — the minimum total diversity of the division of students and the number of teams in your division, correspondingly.
In the second line print n integers t1,t2,…,tn (1≤ti≤k), where ti is the number of team to which the i-th student belong.
If there are multiple answers, you can print any. Note that you don't need to minimize the number of teams. Each team should consist of at least three students.
Topics :
Sorting + DP + Greedy
Solution in Java :
import java.util.*;
import java.lang.*;
import java.io.*;
public class Solution {
static class Student implements Comparable<Student> {
int programmingSkills;
int index;
Student(int programmingSkills, int index) {
this.programmingSkills = programmingSkills;
this.index = index;
}
public int compareTo(Student s) {
return Integer.compare(programmingSkills, s.programmingSkills);
}
}
static int INF = (int) 1e9 + 7;
public static void main(String[] args) throws java.lang.Exception {
out = new PrintWriter(new BufferedOutputStream(System.out));
sc = new FastReader();
int test = 1;
for (int t = 1; t <= test; t++) {
solve();
}
out.close();
}
private static void solve() {
int n = sc.nextInt();
Student[] students = new Student[n];
for (int i = 0; i < n; i++) {
int programmingSkills = sc.nextInt();
students[i] = new Student(programmingSkills, i);
}
Arrays.sort(students);
int[] teamSizes = new int[n + 1]; // size of the team in which ith student is in.
Arrays.fill(teamSizes, -1);
// dp[i] is the minimum total diversity we can get by dividing first i students into teams.
int[] dp = new int[n + 1];
Arrays.fill(dp, INF);
dp[0] = 0;
for (int i = 0; i < n; i++) { // for each student
for (int j = 3; j <= 5 && j <= i + 1; j++) { // for each team size <= 5, since team of sizes > 5 can be divided into smaller teamSizes.
if (dp[i + 1] > dp[i - j + 1] + students[i].programmingSkills - students[i - j + 1].programmingSkills) {
dp[i + 1] = dp[i - j + 1] + students[i].programmingSkills - students[i - j + 1].programmingSkills;
teamSizes[i + 1] = j;
}
}
}
int totalGroups = 0;
int[] groups = new int[n];
for (int i = n; i > 0; ) {
totalGroups++;
for (int j = i - teamSizes[i]; j < i; j++) {
groups[students[j].index] = totalGroups;
}
i -= teamSizes[i];
}
out.println(dp[n] + " " + totalGroups);
for (int i = 0; i < n; i++) {
out.print(groups[i] + " ");
}
out.println();
}
public static FastReader sc;
public static PrintWriter out;
static class FastReader
{
BufferedReader br;
StringTokenizer str;
public FastReader()
{
br = new BufferedReader(new
InputStreamReader(System.in));
}
String next()
{
while (str == null || !str.hasMoreElements())
{
try
{
str = new StringTokenizer(br.readLine());
}
catch (IOException lastMonthOfVacation)
{
lastMonthOfVacation.printStackTrace();
}
}
return str.nextToken();
}
int nextInt()
{
return Integer.parseInt(next());
}
long nextLong()
{
return Long.parseLong(next());
}
double nextDouble()
{
return Double.parseDouble(next());
}
String nextLine()
{
String str = "";
try
{
str = br.readLine();
}
catch (IOException lastMonthOfVacation)
{
lastMonthOfVacation.printStackTrace();
}
return str;
}
}
}