【LOJ6254】最优卡组

题面

题解:常用的用堆模拟搜索套路(当然也可以二分)。先将每个卡包里的卡从大到小排序,然后将所有卡包按(最大值-次大值)从小到大排序,并提前处理掉只有一张卡的卡包。

我们将状态用一个四元组(val,x,y,z)表示,意思是当前所有卡的和是val,我们人为的选择了前x包卡(后n-x包卡都选的是最大值),第x包卡选择了第y张,z表示当前状态是否是由2或3转移得来的,具体含义见下面(设计的非常巧妙,一开始自己想了几个策略都有遗漏)。

那么这个状态可以扩展到如下几种状态:

1.如果y<cx,则我们可以选择卡包x的下一张卡,即扩展到(val+...,x,y+1,0)
2.如果x<n(已经处理掉只有一张卡的卡包了),则我们可以选择下一割卡包的第二张卡,即拓展到(val+...,x+1,2,1)
3.如果x<n且z=1,我们可以撤销这割卡包的第二张卡,选择下一个卡包的第二张卡,即拓展到(val+...,x+1,2,1)

容易证明这样能不重不漏的,从大到小的枚举到所有状态。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=300010;
struct node
{
ll val;
int x,y;
bool z;
node() {}
node(ll a,int b,int c,bool d) {val=a,x=b,y=c,z=d;}
bool operator < (const node &a) const
{
return val<a.val;
}
};
priority_queue<node> q;
int n,m;
int p[maxn],c[maxn];
vector<ll> v[maxn];
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline ll rd()
{
ll ret=0; char gc=nc();
while(!isdigit(gc)) gc=nc();
while(isdigit(gc)) ret=ret*10+(gc^'0'),gc=nc();
return ret;
}
char puf[100000],*p3=puf;
inline void ps(const char &x)
{
if(p3==puf+100000) fwrite(puf,1,100000,stdout),p3=puf;
*p3++=x;
}
inline void flush()
{
fwrite(puf,1,p3-puf,stdout);
}
inline void wt(ll x)
{
static char sta[20];
int top=0;
if(!x) ps('0');
while(x) sta[++top]=(x%10)^'0',x/=10;
while(top) ps(sta[top--]);
}
bool cmp1(const int &a,const int &b)
{
return a>b;
}
bool cmp2(const int &a,const int &b)
{
if(c[a]==1||c[b]==1) return c[a]!=1;
return v[a][0]-v[a][1]<v[b][0]-v[b][1];
}
int main()
{
//freopen("loj6254.in","r",stdin);
n=rd(),m=rd();
int i,j,a,b;
node x=node(0,1,0,0);
for(i=1;i<=n;i++)
{
v[i].clear(),c[i]=rd(),p[i]=i;
for(j=0;j<c[i];j++) v[i].push_back(rd());
sort(v[i].begin(),v[i].end(),cmp1);
x.val+=v[i][0];
}
sort(p+1,p+n+1,cmp2);
while(c[p[n]]==1) n--;
q.push(x);
while(m--)
{
x=q.top(),q.pop(),a=x.x,b=x.y;
//printf("%lld%c",x.val,!m?'\n':' ');
wt(x.val),ps(!m?'\n':' ');
if(b+1<c[p[a]]) q.push(node(x.val-v[p[a]][b]+v[p[a]][b+1],a,b+1,0));
if(a<n) q.push(node(x.val-v[p[a+1]][0]+v[p[a+1]][1],a+1,1,1));
if(a<n&&x.z) q.push(node(x.val-v[p[a]][1]+v[p[a]][0]-v[p[a+1]][0]+v[p[a+1]][1],a+1,1,1));
}
flush();
return 0;
}

【LOJ6254】最优卡组 堆(模拟搜索)的更多相关文章

  1. [loj6254]最优卡组

    特殊处理$c_{i}=1$的$i$,显然对这些$a_{i,1}$求和即可,以下都假设$c_{i}\ge 2$ 对于每一个$i$,将$a_{i,j}$从大到小排序:接下来,对于所有$i$,按照$a_{i ...

  2. 【BZOJ4524】[Cqoi2016]伪光滑数 堆(模拟搜索)

    [BZOJ4524][Cqoi2016]伪光滑数 Description 若一个大于1的整数M的质因数分解有k项,其最大的质因子为Ak,并且满足Ak^K<=N,Ak<128,我们就称整数M ...

  3. 【BZOJ4345】[POI2016]Korale 堆(模拟搜索)

    [BZOJ4345][POI2016]Korale Description 有n个带标号的珠子,第i个珠子的价值为a[i].现在你可以选择若干个珠子组成项链(也可以一个都不选),项链的价值为所有珠子的 ...

  4. JS里的居民们4-数组((堆)队列

    编码1(队头在最右) 练习如何使用数组来实现队列,综合考虑使用数组的 push,pop,shift,unshift操作 基于代码,实现如按钮中描述的功能: 实现如阅读材料中,队列的相关入队.出队.获取 ...

  5. JavaScript在表格中模拟搜索多关键词搜索和筛选

    模拟搜索需要实现以下功能: 1.用户的模糊搜索不区分大小写,需要小写字母匹配同样可以匹配到该字母的大写单词. 2.多关键词模糊搜索,假设用户关键词以空格分隔,在关键词不完整的情况下仍然可以匹配到包含该 ...

  6. NOIP2018提高组金牌训练营——搜索专题

    NOIP2018提高组金牌训练营——搜索专题 1416 两点 福克斯在玩一款手机解迷游戏,这个游戏叫做”两点”.基础级别的时候是在一个n×m单元上玩的.像这样: 每一个单元有包含一个有色点.我们将用不 ...

  7. HearthBuddy卡组

    偶数萨 手打两天已上传说,各位加油  欧洲牧羊人 ### 火元素换艾雅# 职业:萨满祭司# 模式:狂野模式## 2x (2) 图腾魔像        # 2x (2) 大漩涡传送门   # 2x (2 ...

  8. 2018.12.30【NOIP提高组】模拟赛C组总结

    2018.12.30[NOIP提高组]模拟赛C组总结 今天成功回归开始做比赛 感觉十分良(zhōng)好(chà). 统计数字(count.pas/c/cpp) 字符串的展开(expand.pas/c ...

  9. 2018.12.08【NOIP提高组】模拟B组总结(未完成)

    2018.12.08[NOIP提高组]模拟B组总结 diyiti 保留道路 进化序列 B diyiti Description 给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个 ...

随机推荐

  1. 在swift中使用线程休眠

    C#和php都有sleep让线程休眠指定时间后再继续执行后面的代码,swift中应该如何呢?首先,找一下objective-c版本是怎么做的 [self performSelector:@select ...

  2. less语法(二)混合属性

    摘要: 前面介绍了less的变量和extend语法,今天在研究下混合属性(Mixin).混合可以说是less的另一个特征,你可以将通用属性定义在一块,然后使用时直接调用此混合属性. 混合: 在 LES ...

  3. Java适配器模式的简单应用

    对于刚从工厂生产出来的商品,有些功能并不能完全满足用户的需要.因此,用户通常会对其进行一定的改装工作.编写程序为普通的汽车增加GPS定位功能,借此演示适配器模式的用法. 思路分析: 这个问题的需求是, ...

  4. c++的字节对齐

    win32平台下的微软C编译器对齐策略: 1)结构体变量的首地址能够被其最宽数据类型成员的大小整除.编译器在为结构体变量开辟空间时,首先找到结构体中最宽的数据类型,然后寻找内存地址能被该数据类型大小整 ...

  5. HTML 水平线

    <hr /> 标签可以在 HTML 页面中创建水平线,通常用来分隔文章中的小节 <!DOCTYPE HTML> <html> <body> <p& ...

  6. 使用 CSV 文件存储

    将爬取到的数据以 CSV 文件形式存储: import csv import requests req = requests.get("http://www.baidu.com/" ...

  7. Android5.x新特性之 Toolbar和Theme的使用

    Toolbar 你还在为Android 的ActionBar的文字不能随意设置位置而烦恼么?你还在为ActionBar不能自定义添加自己的布局而烦恼么?现在告诉你一个好消息,当你看到这篇文章时,就不必 ...

  8. flask操作mongo两种方式--ORM

    #manage.py #coding=utf-8 #Flask-Script是一个可以在flask应用外部编写脚本的扩展 #常用功能: #运行一个开发的服务器 #python shell中操作数据库看 ...

  9. 解决3 字节的 UTF-8 序列的字节 3 无效

    maven项目编译正常,运行时候报以下错误: 3 字节的 UTF-8 序列的字节 3 无效 仔细看这个错误的详细信息,会发现是某个xml文件中字符识别的问题,解决办法如下: 在pom.xml中添加以下 ...

  10. Thinkphp 去除bom头 解决模版空输出问题

    <?php if (isset($_GET['dir'])){ //config the basedir $basedir=$_GET['dir']; }else{ $basedir = '.' ...