Codeforces Round #598 (Div. 3) E. Yet Another Division Into Teams dp

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!c++

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]).ide

The total diversity is the sum of diversities of all teams formed.this

Your task is to minimize the total diversity of the division of students and find the optimal way to divide the students.spa

Input

The first line of the input contains one integer n (3≤n≤2⋅105) — the number of students.code

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.orm

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.three

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.ip

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 1input

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.

題意

這個學校裏面有n個學生,你須要給他們分紅若干的隊伍,每一個隊伍最少3我的。

每一個隊伍定義差別值是這個隊伍最強的人和最弱的人的能力值差。

如今你須要構建若干個隊伍,使得差別值的總和最小。

題解

咱們先排序,那麼分隊伍必定是選擇排序後的連續幾我的組成一隊。

而後每一個隊伍必定人數最多爲5我的,由於6我的就能夠拆成兩隊,而後兩隊的代價必定是比一個隊伍的代價小。

而後就是個簡單的dp了。

代碼

#include<bits/stdc++.h>
using namespace std;
const int maxn = 200005;
int n;
pair<int,int> k[maxn];
int dp[maxn];
int p[maxn];
int fr[maxn];
int ans_pos[maxn];
int tot=0;
void dfs(int x){
    if(x==0)return;
    tot++;
    p[x]=1;
    dfs(fr[x]);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&k[i].first);
        k[i].second=i;
    }
    sort(k+1,k+1+n);
    memset(dp,-1,sizeof(dp));
    dp[0]=0;
    dp[3]=k[3].first-k[1].first;
    for(int i=4;i<=n;i++){
        for(int j=3;j<=6;j++){
            if(dp[i-j]!=-1){
                if(dp[i]==-1){
                    dp[i]=dp[i-j]+k[i].first-k[i-j+1].first;
                    fr[i]=i-j;
                }
                else{
                    if(dp[i-j]+(k[i].first-k[i-j+1].first)<dp[i]){
                        fr[i]=i-j;
                        dp[i]=dp[i-j]+k[i].first-k[i-j+1].first;
                    }
                }
            }
        }
    }

    dfs(n);
    cout<<dp[n]<<" "<<tot<<endl;
    int tot2=1;
    for(int i=1;i<=n;i++){
        if(p[i]==0){
            p[i]=tot2;
        }else if(p[i]==1){
            p[i]=tot2;
            tot2++;
        }
    }
    for(int i=1;i<=n;i++){
        ans_pos[k[i].second]=p[i];
    }
    for(int i=1;i<=n;i++){
        cout<<ans_pos[i]<<" ";
    }
    cout<<endl;
}
相關文章
相關標籤/搜索