Codeforces Round #598 (Div. 3) E. 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个学生,你需要给他们分成若干的队伍,每个队伍最少3个人。
每个队伍定义差异值是这个队伍最强的人和最弱的人的能力值差。
现在你需要构建若干个队伍,使得差异值的总和最小。*/
/* 大概思路:先排序,然后选择连续的几个人排成一队
每个队为最少3个,最多五个因为6个人就可以拆成两队,两队的差值一定比一个队伍的小
然后 dp*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200005;
int n,tot=0,ans_pos[maxn],fr[maxn],p[maxn],dp[maxn];
pair<int,int> k[maxn];
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;
}

原文地址:https://www.cnblogs.com/QingyuYYYYY/p/11804168.html

时间: 2024-07-30 11:52:27

Codeforces Round #598 (Div. 3) E. Yet Another Division Into Teams dp的相关文章

Codeforces Round #598 (Div. 3) D - Binary String Minimizing

原文链接:https://www.cnblogs.com/xwl3109377858/p/11797618.html Codeforces Round #598 (Div. 3) D - Binary String Minimizing You are given a binary string of length n (i. e. a string consisting of n characters '0' and '1'). In one move you can swap two adj

Codeforces Round #426 (Div. 2) D. The Bakery(线段树维护dp)

题目链接: Codeforces Round #426 (Div. 2) D. The Bakery 题意: 给你n个数,划分为k段,每段的价值为这一段不同的数的个数,问如何划分,使得价值最大. 题解: 考虑dp[i][j]表示划分为前j个数划分为i段的最大价值,那么这就是一个n*n*k的dp, 考虑转移方程dp[i][j]=max{dp[i][k]+val[k+1][j]},我们用线段树去维护这个max,线段树上每个节点维护的值是dp[i][k]+val[k+1][j],对于每加进来的一个数a

Codeforces Round #459 (Div. 2) C 思维,贪心 D 记忆化dp

Codeforces Round #459 (Div. 2) C. The Monster 题意:定义正确的括号串,是能够全部匹配的左右括号串. 给出一个字符串,有 (.). ? 三种字符, ? 可以当作 ( 可 ) . 问这个字符串有多少个子串是正确的括号串. tags:好考思维,想不到.. 预处理出每个字符向左向右最多可以匹配到哪里,再 O(n*n) 枚举所有区间,看是否符合条件. // C #include<bits/stdc++.h> using namespace std; #pra

Codeforces Round #598 (Div. 3)

比赛链接:传送门 A. Payment Without Change 代码: #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <string> #include <queue> #

Codeforces Round #286 (Div. 1) A. Mr. Kitayuta, the Treasure Hunter DP

链接: http://codeforces.com/problemset/problem/506/A 题意: 给出30000个岛,有n个宝石分布在上面,第一步到d位置,每次走的距离与上一步的差距不大于1,问走完一路最多捡到多少块宝石. 题解: 容易想到DP,dp[i][j]表示到达 i 处,现在步长为 j 时最多收集到的财富,转移也不难,cnt[i]表示 i 处的财富. dp[i+step-1] = max(dp[i+step-1],dp[i][j]+cnt[i+step+1]) dp[i+st

Codeforces Round #531 (Div. 3) F. Elongated Matrix(状压DP)

F. Elongated Matrix 题目链接:https://codeforces.com/contest/1102/problem/F 题意: 给出一个n*m的矩阵,现在可以随意交换任意的两行,最后从上到下,从左到右形成一个序列s1,s2.....snm,满足对于任意相邻的两个数,它们差的绝对值的最大值为k. 现在问怎么交换行与行,可以使得最后的这个k最大. 题解: 人生中第一道状压dp~其实还是参考了这篇博客:https://blog.csdn.net/CSDNjiangshan/art

Codeforces Round #291 (Div. 2) E - Darth Vader and Tree (DP+矩阵快速幂)

这题想了好长时间,果断没思路..于是搜了一下题解.一看题解上的"快速幂"这俩字,不对..这仨字..犹如醍醐灌顶啊...因为x的范围是10^9,所以当时想的时候果断把dp递推这一方法抛弃了.我怎么就没想到矩阵快速幂呢.......还是太弱了..sad..100*100*100*log(10^9)的复杂度刚刚好. 于是,想到了矩阵快速幂后,一切就变得简单了.就可以把距离<=x的所有距离的点数都通过DP推出来,然后一个快速幂就解决了. 首先DP递推式很容易想到.递推代码如下: for(

[Codeforces Round #284 (Div. 1) B]Name That Tune(概率Dp)

Description It turns out that you are a great fan of rock band AC/PE. Peter learned that and started the following game: he plays the first song of the list of n songs of the group, and you have to find out the name of the song. After you tell the so

Codeforces Round #321 (Div. 2) D. Kefa and Dishes (状压dp,再A一发)

题意: 有n个菜,需要m个菜,k个规则  每个菜吃下去的满足感为 a1......an 每个规则: 吃完第u个菜后吃第v个菜满足感+c; 问:怎么吃才能幸福感最大? dp[1<<18][20]:一维表示吃了的菜(1表示吃了,0表吃没吃),第二维表示最后一个吃的菜 dp的初始化: dp[1<<i][i] = saty[i]; 状态转移:dp[i|(1 << k)][k] = max(dp[i][j] + rule[j][k] + safy[k],dp[i|(1 <&