Codeforces1256E. Yet Another Division Into Teams dp記錄路徑

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 2

output

Copy

3 1
1 1 1 1 1 

input

Copy

6
1 5 12 13 2 15

output

Copy

7 2
2 2 1 1 2 1 

input

Copy

10
1 2 5 129 185 581 1041 1909 1580 8150

output

Copy

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][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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章