E.Yet Another Division Into Teams
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.
Examples
Input
5
1 1 3 4 2
Output
3 1
1 1 1 1 1
Input
6
1 5 12 13 2 15
Output
7 2
2 2 1 1 2 1
Input
10
1 2 5 129 185 581 1041 1909 1580 8150
Output
7486 3
3 3 3 2 2 2 2 1 1 1
Note
In the first example, there is only one team with skills [1,1,2,3,4] so the answer is 3. It can be shown that you cannot achieve a better answer.
In the second example, there are two teams with skills [1,2,5] and [12,13,15] so the answer is 4+3=7.
In the third example, there are three teams with skills [1,2,5], [129,185,581,1041] and [1580,1909,8150] so the answer is 4+912+6570=7486.
思路:
参考的别人题解。
要使得每组的极差和最小,显然要先把a数组排序
每个队伍的人数为3到5个人,因为如果大于6个人,则可以把这个队拆成两个队伍
答案只减不增(不会变劣)
例如123456,答案为(6-1)=5
如果拆成123和456,则答案为(3-1)+(6-4)=4
d[i]表示安排前i个人的最小花费
初始化d数组为inf
关键代码:
for(int i=1;i<=n;i++){
for(int j=3;j<=5;j++){//枚举以i为第一个队员的队伍长度,则队伍为i~(i+j-1)
int t=d[i-1]+a[i+j-1].v-a[i].v;//d[i-1]为前(i-1)个人的最小花费
if(t<d[i+j-1]){
d[i+j-1]=t;
}
}
}
code:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxm=2e5+5;
const int inf=1e9;
struct Node{
int v,id;
}a[maxm];
int d[maxm];//d[i]表示分配前i个人需要的最小花费
int L[maxm];
int ans[maxm];
int n;
bool cmp(Node a,Node b){
return a.v<b.v;
}
signed main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i].v);
a[i].id=i;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){//初始化inf
d[i]=inf;
}
for(int i=1;i<=n;i++){
for(int j=3;j<=5;j++){//枚举队伍的长度(此时i为开头)
int t=d[i-1]+a[i+j-1].v-a[i].v;//花费为前i-1个人的花费d[i-1]加上a[i+j-1].v-a[i].v
if(t<d[i+j-1]){
d[i+j-1]=t;
L[i+j-1]=i;//记录区间左端点(右端点为i+j-1)
}
}
}
int now=n;
int cnt=0;
while(now){//标记队伍编号
cnt++;
for(int i=L[now];i<=now;i++){
ans[a[i].id]=cnt;
}
now=L[now]-1;
}
printf("%d %d\n",d[n],cnt);
for(int i=1;i<=n;i++){
printf("%d ",ans[i]);
}
puts("");
return 0;
}