【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. JUnit 3一个例子就懂

    JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture f ...

  2. kafka学习之-KafkaOffsetMonitor后台监控

    1.下载Kafka Consumer Offset Monitor安装包 http://pan.baidu.com/s/1ntzIUPN 2.在/usr/local/hadoop路径下面建立放置Kaf ...

  3. windows下卸载oracle11g

    oracle11g卸载   oracle11g卸载 卸载oracle: 1.开始--控制面板--性能和维护--管理工具--服务    停止所有的oracle服务. 2.开始--程序--oracle-- ...

  4. 杨涛老师MvcPager示例

    杨涛老师插件地址:http://www.webdiyer.com/mvcpager 杨涛老师网站上示例写的很详细了,参考他的示例和帮助文档就可以运用的很好了,有经验的同学可以直接参考官方示例. 一.标 ...

  5. HTML5标签embed详解

    摘要: <embed> 标签是 HTML 5 中的新标签,用来定义嵌入的内容,比如插件.类似于HTML 4.01 中的object和applet标签.我们要在网页中正常显示flash内容, ...

  6. 让Json更懂中文(JSON_UNESCAPED_UNICODE)

    我们知道, 用PHP的json_encode来处理中文的时候, 中文都会被编码, 变成不可读的, 类似”\u***”的格式, 还会在一定程度上增加传输的数据量. <?php echo json_ ...

  7. SpringMVC由浅入深day01_1springmvc框架介绍

    springmvc 第一天 springmvc的基础知识 课程安排: 第一天:springmvc的基础知识 什么是springmvc? springmvc框架原理(掌握) 前端控制器.处理器映射器.处 ...

  8. Linux+Redis实战教程_day01_常用命令【重点】

    3.常用命令[重点] Linux命令中参数,一般都是无序的.特殊情况下除外 3.1.磁盘管理命令 ls命令:列出目录内容 参数: -a 查询所有文件和文件夹.包含隐藏的 -l 查询详细列表    ls ...

  9. junit的简单用法

    之前测试一个方法总要写一个main函数来调用,感觉既费事又有点low.今天来简单研究一下怎么使用junit来进行单元测试. 1. 依赖包 <dependency> <groupId& ...

  10. Docker-创建和分享应用(3)

          Dockerfile定义容器内环境中发生的事情.对网络接口和磁盘驱动器等资源的访问在此环境中进行虚拟化,该环境与系统的其他部分隔离,因此您需要将端口映射到外部世界,并具体说明要“复制”哪些 ...