• [loj6254]最优卡组


    特殊处理$c_{i}=1$的$i$,显然对这些$a_{i,1}$求和即可,以下都假设$c_{i}ge 2$

    对于每一个$i$,将$a_{i,j}$从大到小排序;接下来,对于所有$i$,按照$a_{i,1}-a_{i,2}$从小到大排序

    在堆中维护三元组$(S,x,y)$,按照$S$从大到小维护(即堆顶$S$最大),初始在堆中加入$(sum_{i=1}^{n}a_{i,1},1,1)$

    每一次取出堆顶的三元组$(S,x,y)$并输出$S$,接下来:

    1.若$y<c_{x}$,则加入三元组$(S-(a_{x,y}-a_{x,y+1}),x,y+1)$

    2.若$x<n$,则加入三元组$(S-(a_{x+1,1}-a_{x+1,2}),x+1,2,y)$

    3.若$x<n$且$y=2$且$x e 1$,则加入三元组$(S-(a_{x+1,1}-a_{x+1,2})+(a_{x,1}-a_{x,2}),x+1,2,y)$

    显然这一做法的复杂度为$o(nlog n)$,下面来证明其正确性——

    用$d_{i}$去描述一组方案,即表示选择$a_{i,d_{i}}$,其能力值之和即$sum_{i=1}^{n}a_{i,d_{i}}$

    考虑一组方案$d_{i}$,我们对其执行下面两种变化:

    1.若$d_{x}>1$,令$d_{x}$减小1

    2.若$d_{x}=1$且$d_{x+1}=2$(其中$x<1$),交换$d_{x}$和$d_{x+1}$

    不难证明,这样得到的方案一定不劣于$d_{i}$(根据排序即可得到)

    由此,问题也可以看作证明每一个不在堆中且未被选择的方案(以下称为判定方案)$d_{i}$,都存在一个堆中的三元组$(S,x,y)$以及其所对应的方案$d'_{i}$,满足$forall 1le i<x,d'_{i}=d_{i}$且$d_{i}$可以变为$d'_{i}$

    (关于三元组所对应的方案$d'_{i}$,可以通过$S$的变化感性理解,显然其满足$d'_{x}=y,forall x<ile n,d'_{i}=1$)

    关于如何将$d_{i}$变为$d'_{i}$,由于上述特殊条件,显然有以下策略:

    1.若$d_{x}>d'_{x}=y$,则先将$forall x<ile n,d_{i}$都通过1操作变为1,最后再将$d_{x}$减小为$d'_{x}$

    2.若$d_{x}=d'_{x}=y$,若$forall x<kle n,d_{k}=d'_{k}$即已经完成,否则即$exists x<kle n,d_{k} e d'_{k}$($d_{k}>d'_{k}=1$)

    取其中最小的$k$,对于$iin (k,n]$都直接将$d_{i}$通过1操作变为1,再将$d_{k}$变为2,由于$forall x<i<k,d_{i}=d'_{i}=1$,因此直接通过2操作不断交换$d_{k-1}$和$d_{k}$、$d_{k-2}$和$d_{k}$……直至$d_{x+1}=2$,再对$x+1$执行1操作即可

    3.若$d_{x}<d'_{x}=y$,由于增加$d_{x}$只有2操作,且只能增加为2,因此必然$y=2$($d_{x}=1$)

    更进一步的,若$forall x<kle n,d_{k}=d'_{k}=1$即无解,否则类似前面,将$d_{x+1}$变为2,再交换$d_{x}$和$d_{x+1}$即可

    (上述策略并不唯一,但这样有助于下面的分析)

    仍然回到最初的命题,即证明判定方案$d_{i}$都存在都存在一个堆中的三元组$(S,x,y)$以及其所对应的方案$d'_{i}$,满足$forall 1le i<x,d'_{i}=d_{i}$且$d_{i}$可以变为$d'_{i}$

    归纳此命题成立,考虑当我们删除$(S,x,y)$后(设其对应的方案为$d'_{i}$),所有能变为$d'_{i}$的判定方案$d_{i}$(注意这里有$d e d'$,因为$d'$已经被选择),按照上述策略将其操作为$d'$,并撤销最后一次操作,将所有可能得到的方案(即撤销最后一次操作后)都加入,显然仍然满足此条件(每一个$d_{i}$都可以变化为撤销最后一次操作后所产生的方案)

    考虑最后一次操作,实际上只有对$x$执行1操作、对$x+1$执行1操作以及交换$d_{x}$和$d_{x+1}$,因此得到的方案也只有3种,即前面的3种转移所得到的方案(显然方案也符合之前的定义)

    另外,我们还需要说明方案不会重复——

    显然只需要考虑两个不同的方案,分别选择了一种操作后变成了相同的方案,由于$y+1>2$显然不可能

    (一个例外是$(1,1)$和$(1,2)$分别使用第2和3种转移都会产生$(2,1)$,限制$x=1$时不能选择第3种转移即可)

    综上,即证明正确性

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 #define ll long long
     5 struct Data{
     6     int x,y;
     7     ll ans;
     8     bool operator < (const Data &k)const{
     9         if (ans!=k.ans)return ans>k.ans;
    10         return make_pair(x,y)<make_pair(k.x,k.y);
    11     }
    12 };
    13 multiset<Data>s;
    14 vector<int>a[N];
    15 int n,m,x,y,id[N];
    16 ll sum;
    17 bool cmp1(int x,int y){
    18     return x>y;
    19 }
    20 bool cmp2(int x,int y){
    21     return a[x][0]-a[x][1]<a[y][0]-a[y][1];
    22 }
    23 int main(){
    24     scanf("%d%d",&n,&m);
    25     for(int i=1;i<=n;i++){
    26         scanf("%d",&x);
    27         for(int j=1;j<=x;j++){
    28             scanf("%d",&y);
    29             a[i].push_back(y);
    30         }
    31         sort(a[i].begin(),a[i].end(),cmp1);
    32         sum+=a[i][0];
    33         if (x==1){
    34             n--;
    35             a[i--].clear();
    36         }
    37     }
    38     for(int i=1;i<=n;i++)id[i]=i;
    39     sort(id+1,id+n+1,cmp2);
    40     s.insert(Data{1,0,sum});
    41     for(int i=1;i<=m;i++){
    42         Data o=(*s.begin());
    43         s.erase(s.begin());
    44         x=o.x,y=o.y,sum=o.ans;
    45         printf("%lld ",sum);
    46         if (y+1<a[id[x]].size())s.insert(Data{x,y+1,sum-(a[id[x]][y]-a[id[x]][y+1])});
    47         if (x<n)s.insert(Data{x+1,1,sum-(a[id[x+1]][0]-a[id[x+1]][1])});
    48         if ((x<n)&&(y==1)&&(x!=1))s.insert(Data{x+1,1,sum-(a[id[x+1]][0]-a[id[x+1]][1])+(a[id[x]][0]-a[id[x]][1])});
    49     } 
    50 } 
    View Code
  • 相关阅读:
    [原创]K8 Struts2 Exp 20170310 S2-045(Struts2综合漏洞利用工具)
    [原创]Struts2奇葩环境任意文件上传工具
    Nmap扫描基础常用命令(包含进阶使用)
    Burp Suite Intruder中爆破模式介绍
    Debian Security Advisory(Debian安全报告) DSA-4412-1 drupal7 security update
    Debian Security Advisory(Debian安全报告) DSA-4411-1 firefox-esr security update
    Debian Security Advisory(Debian安全报告) DSA-4410-1 openjdk-8 security update
    kindeditor<=4.1.5 文件上传漏洞利用
    Access数据库SQL注入(Access SQL Injection)
    渗透测试常见开放端口及利用
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14848260.html
Copyright © 2020-2023  润新知