题意

n个人,每人有一个能力值a[i],要求分成多个队伍,每个队伍至少3个人,使得所有队伍的max(a[i])-min(a[i])之和最小。

分析

  • 不会巧妙的dp,想了一天只想到了暴力的dp。
  • 先排序,设\(dp[i]\)表示到前i个数组队,所有队伍的最小极差和。
  • 转移方程为\(dp[i]=min(dp[j-1]+a[i]-a[j])\)for j in 1...i-2。即\(dp[i]=a[i]+min(dp[j-1]-a[j])\)。
  • 所以可以枚举i,然后用优先队列维护\(dp[j-1]-a[j]\),注意j最大是i-2。
  • 为了方便最后输出方案,再维护一个len数组,表示前i个人当前i所在队伍的人数,最后从后往前递推,每次\(i-=len[i]-1\),就能标记队伍的分割点,然后类似差分的思想扫一遍即可得到答案。
  • 还有10天就退役了,退役前不会dp,希望退役后能学会dp吧。
  • 突然想到好像可以不用优先队列了,反正只要往一个方向扫同时维护一个最小值就可以了。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+50;
typedef long long ll;
int n;
pair<ll,int> a[N];
ll dp[N];
int ans[N],vis[N],len[N];
queue<int> tmp;
struct node{
ll dp;
int i;
bool operator<(const node& rhs)const{
return dp>rhs.dp;
}
};
priority_queue<node> q;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i].first);
a[i].second=i;
}
sort(a+1,a+1+n);
dp[3]=a[3].first-a[1].first;
len[3]=3;
if(n>=4){
dp[4]=a[4].first-a[1].first;
len[4]=4;
tmp.push(4);
}
if(n>=5){
dp[5]=a[5].first-a[1].first;
len[5]=5;
tmp.push(5);
}
for(int i=6;i<=n;i++){
int t=tmp.front();
q.push(node{dp[t-1]-a[t].first,t});
tmp.pop();
auto mn=q.top();
dp[i]=a[i].first+mn.dp;
len[i]=i-mn.i+1;
tmp.push(i);
}
int team=0;
for(int i=n;i>=1;i--){
vis[i]=++team;
i-=len[i]-1;
}
int c=0;
for(int i=n;i>=1;i--){
if(vis[i]){
c=vis[i];
}
ans[a[i].second]=c;
}
printf("%lld %d\n",dp[n],team);
for(int i=1;i<=n;i++){
printf("%d%c",ans[i],i==n?'\n':' ');
}
return 0;
}

Codeforces1256E_Yet Another Division Into Teams的更多相关文章

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

  2. Codeforces Round #598 (Div. 3)- E. Yet Another Division Into Teams - 动态规划

    Codeforces Round #598 (Div. 3)- E. Yet Another Division Into Teams - 动态规划 [Problem Description] 给你\( ...

  3. Yet Another Division Into Teams

    E. Yet Another Division Into Teams 首先要想明白一个东西,就是当一个小组达到六个人的时候,它一定可以拆分成两个更优的小组. 这个题可以用动态规划来写,用一个数组来保存 ...

  4. Top 10 Universities for Artificial Intelligence

    1. Massachusetts Institute of Technology, Cambridge, MA Massachusetts Institute of Technology is a p ...

  5. Codeforces Round #181 (Div. 2) B. Coach 带权并查集

    B. Coach 题目连接: http://www.codeforces.com/contest/300/problem/A Description A programming coach has n ...

  6. Coach(并查集)

    Description A programming coach has n students to teach. We know that n is divisible by 3. Let's ass ...

  7. WPF SDK研究 之 数据绑定

    这一章介绍数据绑定.本章共计27个示例,全都在VS2008下.NET3.5测试通过,点击这里下载:ConnectedData.rar 1.ShowDataWithoutBinding注: <?M ...

  8. Codeforces Round #598 (Div. 3)

    传送门 A. Payment Without Change 签到. Code /* * Author: heyuhhh * Created Time: 2019/11/4 21:19:19 */ #i ...

  9. CF598: div3解题报告

    CF598:div3解题报告 A: Payment Without Change 思路: 按题意模拟即可. 代码: #include<bits/stdc++.h> using namesp ...

随机推荐

  1. idea中JSP页面不能访问静态资源(图片,js,css)

    必须配置SpringMvc对访问静态资源的支持,idea默认就是在main/webapp 下的文件路径,要在web-info同级的resource文件下放置,JSP中 ${pageContext.re ...

  2. BZOJ 4849 [NEERC2016]Mole Tunnels (模拟费用流)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4849 题解 其实也是模拟费用流,但是这道题和一般的题目不一样,这道题是在一个完全二叉树上 ...

  3. java set 顺序

    在java语言中,提供多种不同的结构来组织对象,Set(集合)是其中的一种,本身是一个接口,其迭代时的顺序取决于其具体实现.典型的实现包括:HashSet:哈希表是通过使用称为散列法的机制来存储信息的 ...

  4. Python argparse 用法总结

    使用argparse的四个基本步骤 创建 ArgumentParser() 对象 调用 add_argument() 方法添加参数 使用 parse_args() 解析添加的参数 # example ...

  5. C++入门经典-例6.11-使用指针变量遍历二维数组

    1:代码如下: // 6.11.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #inc ...

  6. LeetCode19----删除链表的倒数第N个节点

    给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 ...

  7. Eclipse中文插件安装教程

    先运行英文版Eclipse 点击Help选择Install New Software 直接点击Add按钮 Name输入: Babel Location输入: http://download.eclip ...

  8. leetcode-easy-string-14 Longest Common Prefix

    mycode   91.59% class Solution: def longestCommonPrefix(self, strs: List[str]) -> str: if not str ...

  9. VC++获取CPU序列号 CPU ID

    CString strCPUID; unsigned long s1, s2; __asm{ mov eax, 01h xor edx, edx cpuid mov s1, edx mov s2, e ...

  10. 谈一谈 Android 的安全机制?

    1.Android 是基于 Linux 内核的,因此 Linux 对文件权限的控制同样适用于 Android,在 Android 中每个应用都有自己的/data/data/包名 文件夹,该文件夹只能该 ...