LOJ #6035.「雅礼集训 2017 Day4」洗衣服 贪心

这道题的贪心好迷啊~
我们对于两个过程进行单独贪心,然后再翻转一个,把这两个拼起来.
先说一下单独贪心,单独贪心的话就是用一个堆,每次取出最小的,并且把这个最小的加上他单次的,再放进去.这样,我们得到的结果,是对于某些洗衣机,不停地洗,然后把这些洗衣机的时间,混在一起,排个序,由于对于每个洗衣机,如果被用到,那么他就会被不停地用,如果我们稍作改动,就一定会是用小的换来大的,所以这样最优.
我们把两个拼起来为什么是对的呢.对于两个单独的答案,最优的无疑是,翻转之后拼起来,因为如果不是这样,也就是说进行了换位,那么参与交换的原来顶着的甲方的A和己方的B,一定会被大于等于A的C和大于等于B的D所代替,那么这个时候答案一定不会变小.那么为什么我们两个单独的最优答案,在拼接的时候,还是能拼出来最优的呢,这是因为,就像我们在上一段说的,我们的到的最优答案,是无条件最优,也就是说,其他的答案,没有一处会比他好.
冷静地去思考、证明贪心确实是一个不二之选.
(随机堆的随机数是1和0轮换的话,好快啊……二叉堆比左偏树快好多啊……)

#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long LL;
#define read(a) (scanf("%d",&a))
const int L=1000010,N=100010;
struct Heap{
  LL key[N];
  int val[N],n;
  inline void Init(){read(n);}
  inline void build(){
    register int i;
    for(i=1;i<=n;++i)read(val[i]);
    std::sort(val+1,val+(n+1));
    for(i=1;i<=n;++i)key[i]=val[i];
  }
  inline LL top(){return key[1];}
  inline void update(){
    key[1]+=val[1];
    register int index=1,next;
    while(index<=(n>>1)){
      next=index<<1;
      if(next<n&&key[next]>key[next|1])++next;
      if(key[next]>=key[index])return;
      std::swap(key[index],key[next]);
      std::swap(val[index],val[next]);
      index=next;
    }
  }
}Wash,Dry;
LL a[L],b[L];
int l;
inline void Init(){
  read(l);
  Wash.Init(),Dry.Init();
  Wash.build(),Dry.build();
}
inline void work(){
  register int i;
  for(i=1;i<=l;++i){
    a[i]=Wash.top(),Wash.update();
    b[i]=Dry.top(),Dry.update();
  }
}
inline void print(){
  register LL ans=0;
  register int i;
  for(i=1;i<=l;++i)
    ans=std::max(ans,a[i]+b[l-i+1]);
  printf("%lld\n",ans);
}
int main(){
  Init(),work(),print();
  return 0;
}

原文地址:https://www.cnblogs.com/TSHugh/p/8625121.html

时间: 2024-10-10 07:01:05

LOJ #6035.「雅礼集训 2017 Day4」洗衣服 贪心的相关文章

「6月雅礼集训 2017 Day4」qyh(bzoj2687 交与并)

原题传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2687 [题目大意] 给出若干区间,求一个区间的大于等于2的子集,使得 |区间并| 和 |区间交| 的乘积最大. $1\leq n, L_i, R_i \leq 10^6$ [题解] 把区间去掉包含情况,然后进行排序,变成$L_i$和$R_i$都递增的数列. 然后容易发现取得区间一定是连续的一段. 然后我们推一推决策单调性,我把考试的时候推的写在代码里了 然后直接单调队列优化即可. 然后

「6月雅礼集训 2017 Day4」暴力大神hxx

[题目大意] 给出一个n重循环,每重循环有范围$[l, r]$,其中$l$,$r$可能是之前的变量,也可能是常数.求循环最底层被执行了多少次. 其中,保证每个循环的$l$,$r$最多有一个是之前的变量.设所有常数最大值为C. $1 \leq n \leq 26, 1\leq C \leq 10^5$ [题解] 发现构成了一个森林. 树形dp,稍微推一些循环交换顺序等等的性质,然后乘在一起就行了. 大概设f[x,i]表示到了x这个点,x的取值为i,x的子树的执行次数. 转移用个前缀和优化即可.复杂

loj6029 「雅礼集训 2017 Day1」市场

传送门:https://loj.ac/problem/6029 [题解] 考虑如果有一些近似连续的段 比如 2 2 2 3 3 3,考虑在除3意义下,变成0 0 0 1 1 1,相当于整体-2 又:区间增加很容易造成这种段,所以我们猜测可以暴力维护 用一棵线段树即可.(好像真的能暴力维护啊 我不知道怎么证明复杂度) # include <stdio.h> # include <string.h> # include <iostream> # include <al

loj6045 「雅礼集训 2017 Day8」价

传送门:https://loj.ac/problem/6045 [题解] 由于存在完美匹配,所以选择k个药就要选择>=k个药材,我们要求的是选择k个药正好选择k个药材. 那么定义选一种减肥药的代价为-pi+INF,选一种药材的代价为INF,这样最小割肯定是恰好选k个 那么 最后答案就是最小割 - Σ(-pi+INF) [由于减肥药是负的所以要反过来...] 中间连的边要设成比inf大的.. # include <stdio.h> # include <string.h> #

「雅礼集训 2017 Day5」矩阵

填坑填坑.. 感谢wwt耐心讲解啊.. 如果要看这篇题解建议从上往下读不要跳哦.. 30pts 把$A$和$C$看成$n$个$n$维向量,那$A_i$是否加入到$C_j$中就可以用$B_{i,j}$表示了 枚举矩阵$A$,求出它的秩$r$,如果$C$在$A$的线性空间内则$C$可以被$A$表示出来 那么$B$矩阵的方案数就是$(2^{n-r})^n$ 这时候我们可以发现,由于枚举$A$覆盖了所有情况,秩相同的$C$的答案都是一样的 然后就可以打表算答案了.. 60pts 如果不想看可以跳过这段

【loj6029】「雅礼集训 2017 Day1」市场 线段树+均摊分析

题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有四种:区间加.区间下取整除.区间求最小值.区间求和. $n\le 100000$ ,每次加的数在 $[-10^4,10^4]$ 之间,每次除的数在 $[2,10^9]$ 之间. 题解 线段树+均摊分析 和 [uoj#228]基础数据结构练习题 类似的均摊分析题. 对于原来的两个数 $a$ 和 $b$ ( $a>b$ ) ,原来的差是 $a-b$ ,都除以 $d$ 后的差是 $\frac{a-b}d$ ,相当于差也除了 $d$

「6月雅礼集训 2017 Day10」quote

[题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. $1 \leq T \leq 10^5, 1 \leq n \leq 10^7, 1\leq K \leq 10^9$ [题解] 显然引号序列可以看做括号序列,于是我们有了一个$O(n^2)$的dp了. 设$f_{i,j}$表示到第$i$个位置,前面有$j$个左引号没有匹配,的方案数 每次,要么有

「6月雅礼集训 2017 Day7」电报

[题目大意] 有n个岛屿,第i个岛屿有有向发射站到第$p_i$个岛屿,改变到任意其他岛屿需要花费$c_i$的代价,求使得所有岛屿直接或间接联通的最小代价. $1 \leq n \leq 10^5, 1 \leq p_i,c_i \leq 10^9$ [题解] 显然最后是个大环,特判原来就是大环的情况. 考虑每个连通块最多保留多少. 树的答案可以直接dp做出来. 环的答案,根据树的答案dp出来. h[x][0/1]表示当前做到环上第i个点,环是否被切断了,的最大保留价值. 因为环必须被切断一次.所

「6月雅礼集训 2017 Day8」gcd

[题目大意] 定义times(a, b)表示用辗转相除计算a和b的最大公约数所需步骤. 那么有: 1. times(a, b) = times(b, a) 2. times(a, 0) = 0 3. times(a, b) = times(b, a mod b) + 1 对于$1 \leq x \leq A, 1 \leq y \leq B$,求times(A, B)的最大值,以及有多少对数取到了最大值. 多组数据. $T \leq 3 \times 10^5, 1 \leq A,B \leq