链接

大意:给定$nk$块木板, 要制作$n$个$k$块板的桶, 要求任意两桶容积差不超过$l$, 每个桶的容积为最短木板长, 输出$n$个桶的最大容积和

假设最短板长$m$, 显然最后桶的体积都在$[m,m+l]$范围内, 就是说需保证每个桶都至少有一块板在$[m,m+l]$范围.

考虑贪心逐步调整, 假设$m+l$足够多的话, 可以先尽量连续得选最短的边做桶, 最后将$m+l$分给剩余桶即为最大容积.

如果不够多的话, 就要选出$m+l-1$分给剩余桶, 还不够就选择$m+l-2$, 直到所有桶都分到为止.

离散化后预处理一下前缀和可以达到复杂度$O(nlogk+nlogn)$

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll; const int N = 4e5+10, INF = 0x3f3f3f3f;
int n, k, l;
int a[N], b[N], cnt[N], s[N]; //用a记录离散化后的值, b是离散化辅助数组
//cnt记录每个离散化后的值的出现次数, s统计cnt的前缀和 ll solve(int n, int x) {
//当前最大的为x, 还要制作n个桶的最大容积和
int t = (s[x-1]+k-1)/k;
if (t+cnt[x]>=n) {
//x数量足够, 直接贪心分配
ll ans = 0;
REP(i,1,n) {
if (a[(i-1)*k+1]<x) ans += b[a[(i-1)*k+1]];
else ans += b[x];
}
return ans;
}
//x不够的话, 先尽量把x分完, 求出第一个比x小的数, 递归计算
auto p = lower_bound(a+1,a+1+n*k,x);
return solve(n-cnt[x],*(--p))+(ll)cnt[x]*b[x];
} int main() {
scanf("%d%d%d", &n, &k, &l);
REP(i,1,n*k) scanf("%d", a+i);
sort(a+1,a+1+n*k);
ll mx = a[1]+l;
if (a[n]>mx) return puts("0"),0;
REP(i,1,n*k) b[i]=a[i];
*b = unique(b+1,b+1+n*k)-b-1;
REP(i,1,n*k) a[i]=lower_bound(b+1,b+1+*b,a[i])-b;
REP(i,1,n*k) ++cnt[a[i]];
REP(i,1,*b) s[i]=s[i-1]+cnt[i];
int p = upper_bound(b+1,b+1+*b,mx)-b-1;
printf("%lld\n", solve(n,p));
}

看了下别人题解, 发现没必要这么麻烦, 上述分析已经知道, 最优结构一定是先连续选一段最小的, 再将$[m,m+l]$中剩余的逐个分给剩余桶

假设连续部分做了x个桶, 剩余部分y个桶, 就有$xk+y<=s[m+l],x+y=n$

解出x的最大值, 就可以直接得到最优解的结构了

Liebig's Barrels CodeForces - 985C (贪心)的更多相关文章

  1. codeforce 985C Liebig's Barrels(贪心+思维)

    Liebig's Barrels time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  2. CF985C Liebig's Barrels 贪心 第二十

    Liebig's Barrels time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  3. Codeforce Div-2 985 C. Liebig's Barrels

    http://codeforces.com/contest/985/problem/C C. Liebig's Barrels time limit per test 2 seconds memory ...

  4. codeforces 985C Liebig's Barrels(贪心)

    题目 题意: 有n * k块木板,每个木桶由k木板组成,每个木桶的容量定义为它最短的那块木板的长度. 任意两个木桶的容量v1,v2,满足|v1-v2| <= d. 问n个木桶容量的最大的和为多少 ...

  5. codeforces 985C Liebig's Barrels

    题意: 有n * k块木板,每个木桶由k木板组成,每个木桶的容量定义为它最短的那块木板的长度. 任意两个木桶的容量v1,v2,满足|v1-v2| <= d. 问n个木桶容量的最大的和为多少,或者 ...

  6. C. Liebig's Barrels

    You have m = n·k wooden staves. The i-th stave has length ai. You have to assemble nbarrels consisti ...

  7. CodeForces - 893D 贪心

    http://codeforces.com/problemset/problem/893/D 题意 Recenlty Luba有一张信用卡可用,一开始金额为0,每天早上可以去充任意数量的钱.到了晚上, ...

  8. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 831D) - 贪心 - 二分答案 - 动态规划

    There are n people and k keys on a straight line. Every person wants to get to the office which is l ...

  9. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 828D) - 贪心

    Arkady needs your help again! This time he decided to build his own high-speed Internet exchange poi ...

随机推荐

  1. Linux基础命令---chgrp

    chgrp 改变文件或者目录所属的群组,使用参数“--reference”,可以改变文件的群组为指定的关联文件群组. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.o ...

  2. spoj1825 Free tour II

    题目链接 一道神奇的点分治 貌似有很多做法,我觉得BIT要好些一些(雾 要求经过黑点数<k就用BIT区间查询前缀 对于每个点用  BIT[0,k-经过黑点数]的最大值+路径长度 使用点分治做到O ...

  3. WireShark学习

    1.打开wireshark->Capture->Interface->选择你的网卡(选中)->Start 2.OK抓包开始,工具栏上有stop,点击停止抓包 3.过滤,这个你可 ...

  4. WiFi攻击的三种方式

    WiFi的安全问题已经引起了不少的使用者重视,甚至已经出现草木皆兵的现象.那么黑客到底是如何做到绕过身份验证来获取WiFi使用权的呢?主要有以下三种方式,其中最后一种方式十分简单. WiFi的安全问题 ...

  5. 计算概论(A)/基础编程练习1(8题)/7:奇数求和

    #include<stdio.h> int main() { // 输入非负整数 int m, n; scanf("%d %d", &m, &n); / ...

  6. MySQL Crash Course #09# Chapter 17. Combining Queries: UNION

    INDEX UNION Rules WHERE VS. UNION UNION VS. UNION ALL Sorting Combined Query Results UNION Rules As ...

  7. 解决mysql的Too many connections

    解决: /etc/my.cnf vim编辑 添加 max_connections= wait_timeout= 然后执行code service mysqld reload service mysql ...

  8. 20144303石宇森《网络对抗》注入shellcode和Return-to-libc攻击

    20144303石宇森<网络对抗>PC平台逆向破解 实验1:shellcode注入 实验基础 1.Linux下有两种基本构造攻击buf的方法:retaddr+nop+shellcode,n ...

  9. Windows10 蓝屏 DRIVER_IRQL_NOT_LESS_OR_EQUAL (vfilter.sys)的可能解决方法

    早上我的笔记本从休眠中开机的时候突然出现了蓝屏,这个蓝屏在前几天出现过了.两次提示的终止代码都一样.我的笔记本型号是DELL XPS15 9560 我的笔记本配置: 类别 型号 内存 16GB DDR ...

  10. my normal Header

    #ifndef INCLUDES_MY #define INCLUDES_MY //默认登录名密码 #define DEFAULT_USERNAME "admin" #define ...