E. Yet Another Division Into Teams

题目链接
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
There are 𝑛 students at your university. The programming skill of the 𝑖-th student is 𝑎𝑖. 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 𝑘 students with programming skills 𝑎[𝑖1],𝑎[𝑖2],…,𝑎[𝑖𝑘], then the diversity of this team is max𝑗=1𝑘𝑎[𝑖𝑗]−min𝑗=1𝑘𝑎[𝑖𝑗]).

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 𝑛 (3≤𝑛≤2⋅105) — the number of students.

The second line of the input contains 𝑛 integers 𝑎1,𝑎2,…,𝑎𝑛 (1≤𝑎𝑖≤109), where 𝑎𝑖 is the programming skill of the 𝑖-th student.

Output
In the first line print two integers 𝑟𝑒𝑠 and 𝑘 — the minimum total diversity of the division of students and the number of teams in your division, correspondingly.

In the second line print 𝑛 integers 𝑡1,𝑡2,…,𝑡𝑛 (1≤𝑡𝑖≤𝑘), where 𝑡𝑖 is the number of team to which the 𝑖-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
inputCopy
5
1 1 3 4 2
outputCopy
3 1
1 1 1 1 1
inputCopy
6
1 5 12 13 2 15
outputCopy
7 2
2 2 1 1 2 1
inputCopy
10
1 2 5 129 185 581 1041 1909 1580 8150
outputCopy
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.

题意:给你n个数,分组,每组最少三人,使最后每组中的最大值与最小值的差的总和最小
分析:首先要从小到大排序,肯定是连续的分组才能保证差最小,分组的话每个组最多5人(假设中间的两个数都不相等),6人的话可以分为两组,然后进行dp(下面会说),然后遍历一遍分组就好了。
dp[]:前n个数的分完组后的差的和(最小的)
ans[]:最后输出的分组情况
tp[]:某分组的区间[tp[n],n]
代码:

#include <bits/stdc++.h>
using namespace std;
pair<int,int>s[200005];
int dp[200005],tp[200005],ans[200005];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&s[i].first);
        s[i].second=i;
    }
    sort(s+1,s+1+n);
    dp[3]=s[3].first-s[1].first;
    int cnt=-1;
    int min1=1e9;
    for(int i=4;i<=n;i++)
    {
        if(i>=6 && min1>dp[i-3]-s[i-2].first)
        {
            min1=dp[i-3]-s[i-2].first;
            cnt=i-2;
        }
        dp[i]=dp[i-1]+s[i].first-s[i-1].first;
        tp[i]=tp[i-1];
        if(min1+s[i].first<dp[i])//再加一个分组可以使差减小
        {
            dp[i]=min1+s[i].first;//dp[i]=dp[i-3]+s[i].first-s[i-2].sirst
            tp[i]=cnt;//记录区间
        }
    }
    int tmp=tp[n],i,pos=1;
    //printf("%d\n",tp[n]);
    for(i=n;i>=0;i--)
    {
        ans[s[i].second]=pos;
        if(i==tmp)
        {
            tmp=tp[i-1];
            pos++;
        }
    }
    printf("%d %d\n",dp[n],pos-1);
    for(i=1;i<n;i++)
        printf("%d ",ans[i]);
    printf("%d",ans[n]);
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值