题意:一个集合S的优美值定义为:最大的x,满足对于任意i∈[1,x],都存在一个S的子集S',使得S'中元素之和为i。

给定n个集合,对于每一次询问,指定一个集合S1和一个集合S2,以及一个数k,要求选择一个S2的子集S3(|S3|<=k),使得S1∪S3的优美值最大。
(集合元素可以重复)
 
我们首先考虑对于集合S1,能否求出它的最大优美值。
  首先排序一遍,对于前i个元素,如果它的最大优美值为v,那么当S1[i+1]>v+1时,前i+1个元素的最大优美值依然为v,否则为v+S1[i+1].此处易证。
  也就是说集合S1的最大优美值等于排序后集合S1的使得S1[i+1]>Sum[i]+1成立的最大前缀和.
再考虑S2到底加入哪些元素可以使得S1的优美值最大呢。
  首先可以肯定的是,由于加入的元素数量有限制,因此S2应该尽量加对S1的优美值增加最大的元素,由上面可以得知,应该为使得S2[i]<=v+1的最大的S2[i].
  这样之后v就变成了v+S2[i],此时集合S1又有可能有元素可以利用了,这样一直进行K次。
要确保算法复杂度即可能低的情况下,可以使用单调队列来维护上面的操作。
因此,总时间复杂度为O(log(nm)+T*m).
 
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <bitset>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
inline int Scan() {
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... VI v[N];
LL val[N], que[N];
int p[N], head, tail; void sol(int x, int &q, LL &w){
FO(i,q,v[x].size()) {
if (v[x][i]>w+) break;
w+=v[x][i]; ++q;
}
}
int main ()
{
int n, m, x, A, B, K, T;
n=Scan();
FOR(i,,n) {
m=Scan();
while (m--) x=Scan(), v[i].pb(x);
sort(v[i].begin(),v[i].end());
p[i]=m;
FO(j,,v[i].size()) {
if (v[i][j]>val[i]+) {p[i]=j; break;}
val[i]+=v[i][j];
}
}
T=Scan();
while (T--) {
A=Scan(); B=Scan(); K=Scan();
int q=p[A];
LL w=val[A];
head=-; tail=;
FO(i,,v[B].size()) {
while (v[B][i]>w+) {
if (head<tail || !K) break;
if (head>=tail&&K) w+=que[head], sol(A,q,w), --head, --K;
}
if (v[B][i]<=w+) {
que[++head]=v[B][i];
while (head-tail+>K) ++tail;
}
if (head<tail || !K) break;
}
if (K) while (head>=tail) w+=que[tail], sol(A,q,w), ++tail;
printf("%lld\n",w);
}
return ;
}

51nod 1821 最优集合(思维+单调队列)的更多相关文章

  1. 51NOD 1821 最优集合 栈

    1821 最优集合   一个集合S的优美值定义为:最大的x,满足对于任意i∈[1,x],都存在一个S的子集S',使得S'中元素之和为i. 给定n个集合,对于每一次询问,指定一个集合S1和一个集合S2, ...

  2. 51NOD 1821 最优集合 [并查集]

    传送门 题意: 一个集合S的优美值定义为:最大的x,满足对于任意i∈[1,x],都存在一个S的子集S',使得S'中元素之和为i. 给定n个集合,对于每一次询问,指定一个集合S1和一个集合S2,以及一个 ...

  3. 【洛谷】【动态规划+单调队列】P1725 琪露诺

    [题目描述:] 在幻想乡,琪露诺是以笨蛋闻名的冰之妖精. 某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来.但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸.于是琪露诺决定到河 ...

  4. poj 1821 Fence(单调队列优化DP)

    poj 1821 Fence \(solution:\) 这道题因为每一个粉刷的人都有一块"必刷的木板",所以可以预见我们的最终方案里的粉刷匠一定是按其必刷的木板的顺序排列的.这就 ...

  5. poj 1821 Fence 单调队列优化dp

    /* poj 1821 n*n*m 暴力*/ #include<iostream> #include<cstdio> #include<cstring> #incl ...

  6. 51nod 1275 连续字段的差异(单调队列)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1275 题意: 思路: 固定某个端点,然后去寻找满足能满足要求的最大区间, ...

  7. 51nod 1050 循环数组最大子段和 单调队列优化DP

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 这个呢,这个题之前 求一遍最大值  然后求一遍最小值 ...

  8. POJ - 1821 单调队列优化DP + 部分笔记

    题意:n个墙壁m个粉刷匠,每个墙壁至多能被刷一次,每个粉刷匠要么不刷,要么就粉刷包含第Si块的长度不超过Li的连续墙壁(中间可不刷),每一块被刷的墙壁都可获得Pi的利润,求最大利润 避免重复粉刷: 首 ...

  9. POJ 1821 单调队列+dp

    题目大意:有K个工人,有n个墙,现在要给墙涂色.然后每个工人坐在Si上,他能刷的最大范围是Li,且必须是一个连续子区间,而且必须过Si,他刷完后能获得Pi钱 思路:定义dp[i][j]表示前i个人,涂 ...

随机推荐

  1. # 第二周c实践所遇见的问题

    第二周c实践所遇见的问题 地址符 在编程练习中时常忘记写入地址符,造成过运行错误,运行结果错误的惨痛教训,一个小小的错误耗费了很长的时间来寻找错误之处,养成写代码的一些好习惯势在必行.牢记scanf( ...

  2. 20145234黄斐《java程序设计》第二周

    教材学习内容总结 类型 Java可区分为基本类型(Primitive Type)和类类型(Class Type),其中类类型也叫参考类型(Reference Type). 字节类型,也叫byte类型, ...

  3. (The application/json Media Type for JavaScript Object Notation (JSON))RFC4627-JSON格式定义

    原文  http://laichendong.com/rfc4627-zh_cn/ 摘要 JavaScript Object Notation (JSON)是一个轻量级的,基于文本的,跨语言的数据交换 ...

  4. day8 RHCE

    12 .实现一个 web 服务器在server0上配置一个站点http://server0.example.com,然后执行以下步骤: 从http://classroom.example.com/ma ...

  5. MySQL入门篇(二)之常见命令管理

    一.SQL结构化查询语言 SQL,英文全称Structured Query Language,中文意思是结构化查询语言.它是一种对关系数据库中的数据进行定义和操作的语言方法,是大多数关系数据库管理系统 ...

  6. 收集的PHP工具及类库

    composer     PHP的依赖管理工具 phpmig        PHP的数据库迁移工具,依赖于composer Requests for PHP    HTTP请求库,采集页面可以用到的 ...

  7. DSP5509项目之用FFT识别钢琴音调(4)之麦克风输入和Line in输入

    1. 麦克风输入需要修改的内容,之前的版本是LINE IN的输入.实现功能,检测麦克风的输入,并且同时在耳机里面播放. #include <csl.h> #include <csl_ ...

  8. RestQL:现代化的 API 开发方式

    参考:https://tech.meituan.com/koa-restql.html 在现代的业务系统中,后端开发工作基本上可以被拆分为三项: 接口鉴权.例如判断是不是当前系统的用户,以及该用户是否 ...

  9. 一个web应用的诞生(2)--使用模板

    经过了第一章的内容,已经可以做出一些简单的页面,首先用这种方式做一个登录页面,首先要创建一个login的路由方法: @app.route("/login",methods=[&qu ...

  10. Introduction to Locking in SQL Server

    Locking is a major part of every RDBMS and is important to know about. It is a database functionalit ...