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!
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]).
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 n (3≤n≤2⋅105) — the number of students.
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.
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.
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
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 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个学生,你需要给他们分成若干的队伍,每个队伍最少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;
}
Codeforces Round #598 (Div. 3) E. Yet Another Division Into Teams dp的更多相关文章
- Codeforces Round #598 (Div. 3)- E. Yet Another Division Into Teams - 动态规划
Codeforces Round #598 (Div. 3)- E. Yet Another Division Into Teams - 动态规划 [Problem Description] 给你\( ...
- 【CF1256】Codeforces Round #598 (Div. 3) 【思维+贪心+DP】
https://codeforces.com/contest/1256 A:Payment Without Change[思维] 题意:给你a个价值n的物品和b个价值1的物品,问是否存在取物方案使得价 ...
- Codeforces Round #396 (Div. 2) A B C D 水 trick dp 并查集
A. Mahmoud and Longest Uncommon Subsequence time limit per test 2 seconds memory limit per test 256 ...
- Codeforces Round #598 (Div. 3)E(dp路径转移)
题:https://codeforces.com/contest/1256/problem/E 题意:给一些值,代表队员的能力值,每组要分3个或3个以上的人,然后有个评价值x=(队里最大值-最小值), ...
- Codeforces Round #598 (Div. 3)
传送门 A. Payment Without Change 签到. Code /* * Author: heyuhhh * Created Time: 2019/11/4 21:19:19 */ #i ...
- Codeforces Round #598 (Div. 3) F. Equalizing Two Strings 构造
F. Equalizing Two Strings You are given two strings s and t both of length n and both consisting of ...
- Codeforces Round #598 (Div. 3) D. Binary String Minimizing 贪心
D. Binary String Minimizing You are given a binary string of length n (i. e. a string consisting of ...
- Codeforces Round #598 (Div. 3) C. Platforms Jumping 贪心或dp
C. Platforms Jumping There is a river of width n. The left bank of the river is cell 0 and the right ...
- Codeforces Round #598 (Div. 3) B. Minimize the Permutation 贪心
B. Minimize the Permutation You are given a permutation of length n. Recall that the permutation is ...
随机推荐
- 【Cocos谁学谁会】定制属于自己的脚本模板
版权申明: 本文原创首发于以下网站,您可以自由转载,但必须加入完整的版权声明 博客园:https://www.cnblogs.com/MogooStudio/ csdn博客:https://blog. ...
- Step by Step Process of Migrating non-CDBs and PDBs Using ASM for File Storage (Doc ID 1576755.1)
Step by Step Process of Migrating non-CDBs and PDBs Using ASM for File Storage (Doc ID 1576755.1) AP ...
- Nginx基础知识点总结和优化项
1.什么是Nginx? Nginx是一个高性能的HTTP和反向代理服务器,常用于做负载均衡服务器 2.为什么要用Nginx?跨平台.配置简单非阻塞.高并发连接:处理2-3万并发连接数,官方监测能支持5 ...
- 【cf960G】G. Bandit Blues(第一类斯特林数)
传送门 题意: 现在有一个人分别从\(1,n\)两点出发,包中有一个物品价值一开始为\(0\),每遇到一个价值比包中物品高的就交换两个物品. 现在已知这个人从左边出发交换了\(a\)次,从右边出发交换 ...
- qq cookie
qq cookie from selenium import webdriver from selenium.webdriver import ActionChains import time, re ...
- python-参数化-(1)(手机号码)
一.生成手机号码,此处并没有写成类或者函数形式,上代码 import random #指定手机号码前三位格式,并随机返回一个区号,关于random参数化的相关部分自行了解type_mobile = [ ...
- Swoole编译安装步骤
Swoole扩展是按照php标准扩展构建的.使用phpize来生成php编译配置,./configure来做编译配置检测,make进行编译,make install进行安装. 请下载releases版 ...
- IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路
1.引言 在即时通讯网经常能看到各种高大上的高并发.分布式.高性能架构设计方面的文章,平时大家参加的众多开发者大会,主题也都是各种高大上的话题——什么5G啦.AI人工智能啦.什么阿里双11分分钟多少万 ...
- C和C++常见误区以及问题整理
c和c++的关系 c是面向过程的语言,c++是在c的基础上扩展的面向对象的编程语言. c++具备c的所有功能,对c的库完全兼容. c++的标准在98年确定,在那之前已经有一些库大量使用. 新标准中,推 ...
- C语言结构选择语句
总结一下常用的if else与switch,其中switch中的break知识点是笔试题经常考到的内容. if else与else if 在C语言中,经常使用if else选择语句,来实现很多对应的功 ...