There are nn students at your university. The programming skill of the ii-th student is aiai. 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⋅1052⋅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 kk students with programming skills a[i1],a[i2],…,a[ik]a[i1],a[i2],…,a[ik], then the diversity of this team is maxj=1ka[ij]−minj=1ka[ij]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 nn (3≤n≤2⋅1053≤n≤2⋅105) — the number of students.
The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109), where aiai is the programming skill of the ii-th student.
Output
In the first line print two integers resres and kk — the minimum total diversity of the division of students and the number of teams in your division, correspondingly.
In the second line print nn integers t1,t2,…,tnt1,t2,…,tn (1≤ti≤k1≤ti≤k), where titi is the number of team to which the ii-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
Copy
5 1 1 3 4 2output
Copy
3 1 1 1 1 1 1input
Copy
6 1 5 12 13 2 15output
Copy
7 2 2 2 1 1 2 1input
Copy
10 1 2 5 129 185 581 1041 1909 1580 8150output
Copy
7486 3 3 3 3 2 2 2 2 1 1 1Note
In the first example, there is only one team with skills [1,1,2,3,4][1,1,2,3,4] so the answer is 33. It can be shown that you cannot achieve a better answer.
In the second example, there are two teams with skills [1,2,5][1,2,5] and [12,13,15][12,13,15] so the answer is 4+3=74+3=7.
In the third example, there are three teams with skills [1,2,5][1,2,5], [129,185,581,1041][129,185,581,1041] and [1580,1909,8150][1580,1909,8150] so the answer is 4+912+6570=74864+912+6570=7486.
题意:n个数分组每组的数的个数至少三个求如何分组才能使分组之后各组的极差之和最小。
思路要想分组时的极差最小那肯定也就需要排一下序让差距小的在一块每组最少三个人所以前三个人肯定是一组的后面的一般状况 我要选第i个人第i个人的能力值肯定要计算在内(因为我从小到大排序的),既然最小要分三个人那就以三个人为基础假设当前第i个人要和前两个组一个新队那就需要判断组一个新队所增加的极差值是不是要比原来并入新组的小,这时候就拿一个变量记录分界点把分界点作为路径记录这是一个之前没遇到的新思路!
#include <iostream>
#include <cstdio>
#include <set>
#include <map>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
long long int dp[200100],tem[200100],pre[200100];
struct ab{
int x,y;
bool operator<(const ab &u)const{
return x<u.x;
}
}a[200100];
long long int n,m;
long long int ans,res,cnt,temp,p;
const int N=110;
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].x;
a[i].y=i;
}
sort(a+1,a+1+n);
dp[0]=0;
dp[1]=1e18;
dp[2]=1e18;
memset(pre,-1,sizeof(pre));
ans=1e18,p=-1;
for(int i=3;i<=n;i++){
if(dp[i-3]-a[i-2].x<ans){//这个就是dp的关键所在判断是否能开一个新组
ans=dp[i-3]-a[i-2].x;
p=i-3;
}
dp[i]=ans+a[i].x;
pre[i]=p;
}
long long pr=n;
vector<long long>op;
while(pr>0){
op.push_back(pr);
pr=pre[pr];
}
reverse(op.begin(),op.end());
for(int i=1;i<=op[0];i++)
tem[a[i].y]=1;
for(int i=1;i<op.size();i++){
for(int j=op[i-1]+1;j<=op[i];j++){
tem[a[j].y]=i+1;//分组的编号每个路径端点就是分组的的界再根据这个倒推下标
}
}
cout<<dp[n]<<' '<<op.size()<<endl;
for(int i=1;i<=n;i++)
cout<<tem[i]<<' ';
cout<<endl;
}