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

给定n个集合,对于每一次询问,指定一个集合S1和一个集合S2,以及一个数k,要求选择一个S2的子集S3(|S3|<=k),使得S1∪S3的优美值最大。
(集合元素可以重复)

Input第一行一个数n,(n<=1000) 
接下来n行,每行描述一个集合: 
第一个数m,表示集合大小,接下来m个数,表示集合中的元素(m<=1000,元素<=10^9) 
第n+2行一个数T,表示询问次数(T<=10000) 
接下来T行,每行3个数a,b,k,表示指定第a个集合为S1,第b个集合为S2,k的意义如题(a<=n,b<=n,k<=100,000)OutputT行,每行一个数,表示对应询问所能达到的最大优美值Sample Input

2
6 1 2 3 8 15 32
6 1 1 1 1 1 1
1
1 2 3

Sample Output

64

题意:给出N个数列。Q次询问,每次询问形如(a,b,k),表示选定第a个数列,然后在b数列里选择k个数,使得ans最大,满足1到ans都可以被表示为这些选择的数的和的形式。

思路:先看子问题:给定一个数列,如何求最大的ans; 假设已经选出一些数,ans=[1,x],如现在给出一个数t<=x+1,那么ans=[1,x+t],负责ans不变。

所以现在即是排序,求出每个集合是ans,然后考虑在b数列选择最大的数t<=ans+1,更新ans=ans+t;同时,a数列的数可以随便选。

#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int a[maxn][maxn],ans[maxn],pos[maxn];
void read(int &x){
x=; char c=getchar();
while(c>''||c<'') c=getchar();
while(c>=''&&c<='') x=(x<<)+(x<<)+c-'',c=getchar();
}
int main()
{
int N,Q,x,y,k,i,j;
read(N);
for(i=;i<=N;i++){
read(a[i][]);
for(j=;j<=a[i][];j++)
read(a[i][j]);
}
for(i=;i<=N;i++){
sort(a[i]+,a[i]+a[i][]+);
for(j=;j<=a[i][];j++){
if(a[i][j]<=ans[i]+) pos[i]=j, ans[i]+=a[i][j];
else break;
}
}
scanf("%d",&Q);
while(Q--){
read(x); read(y); read(k);
int res=ans[x];
priority_queue<int>q;
int np=upper_bound(a[y]+,a[y]+a[y][]+,res+)-a[y],tk=k;
for(i=np-;i>=&&tk;i--){
q.push(a[y][i]); tk--;
} //先挑大的选,这样k后面几个就可以不加进来。 是个小小的优化。
i=np;
int tp=pos[x];
while(k--&&!q.empty()){
res+=q.top();q.pop();
while(tp+<=a[x][]&&a[x][tp+]<=res+) tp++,res+=a[x][tp];
for(;i<=a[y][];i++)
if(a[y][i]<=res+) q.push(a[y][i]);
else break;
}
printf("%d\n",res);
}
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. 51nod 1821 最优集合(思维+单调队列)

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

  4. javascript集合求交集

    两集合求交集 思路: 1. 每一次从B数组中取一值,然后在A数组里逐个比较,如果有相等的,则保存.该算法复杂度为 O(MN). M, N 分别为数组 A B 的长度. 2. 因为A B 都排过序,所以 ...

  5. 集合求交集 & 去除列表中重复的元素

    集合求交集: set1 = {1,2,3,4,5} set2 = {4,5,6,7,8} 交集:set3 = set1 & set2 print(ste3) #结果为{4,5} 或者ste1. ...

  6. 51nod 1206 Picture 矩形周长求并 | 线段树 扫描线

    51nod 1206 Picture 矩形周长求并 | 线段树 扫描线 #include <cstdio> #include <cmath> #include <cstr ...

  7. Uber优步北京第一组奖励政策

    优步北京第一组: 定义为2015年6月1日凌晨前(不含6月1日)激活的司机(以优步后台数据显示为准) 滴滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机 ...

  8. 6月29-7月5日成都uber优步司机第一/二/三组奖励政策明细

    成都优步司机第一/二/三组奖励更新了,在写下文之前,我先吐槽一下:靠优步uber发财致富已成往事. 滴滴快车单单2.5倍,注册地址:http://www.udache.com/如何注册Uber司机(全 ...

  9. Java面试题10(如何取到set集合的第一个元素)

    1.如何取到set集合的第一个元素. public static void main(String[] args) { Set set = new HashSet(); set.add("x ...

随机推荐

  1. iOS -- SKTransition类

      SKTransition类 继承自 NSObject 符合 NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framewor ...

  2. Java Unsafe类

    参考了这篇文章:http://blog.csdn.net/aesop_wubo/article/details/7537278 <JAVA并发编程学习笔记之Unsafe类> Unsafe开 ...

  3. 安装 - LNMP一键安装包

    https://lnmp.org/ 系统需求: CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian Linux系统 需要5GB以上硬盘剩余空间 需要128MB以上内存( ...

  4. 怎样高速启动Android模拟器(Android Emulator)

    总所周知,每次我们启动Android Emulator,都须要花费非常长一段时间,几分钟甚至十几分钟.事实上,我们能够使用快照(Snapshot)功能,来高速启动Android模拟器. 首先.须要在A ...

  5. Spring集成JDBC

    不同spring版本合成的方式,有时候不一样,需要查看帮助文档来看如何集成,帮助文档在spring发行包中. 1.导入spring的包(这里吧Spring-3.1.3 Release的所有jar包都导 ...

  6. MyEclipse的实体关系设计

    原文地址:http://www.myeclipsecn.com/learningcenter/database-development/myeclipse-entity-relation-design ...

  7. 随便写一点最近开发遇到的问题和解决方法 大部分关于laravel和php

    laravel里要想对对象进行自己设计的排序(usort()), 得用匿名方法,  原声php就不用 php里面可以随便写html代码,  比如可以把html直接后缀名改成.php, 然后在任何地方& ...

  8. UVA 1541 - To Bet or Not To Bet(概率递推)

    UVA 1541 - To Bet or Not To Bet 题目链接 题意:这题题意真是神了- -.看半天,大概是玩一个游戏,開始在位置0.终点在位置m + 1,每次扔一个硬币,正面走一步,反面走 ...

  9. poj3181 Dollar Dayz

    Description Farmer John goes to Dollar Days at The Cow Store and discovers an unlimited number of to ...

  10. Process Autocad by python

    一.处理AutoCad模块 -pyautocad 1.安装 pip install pyautocad 注:1.该操作会自动安装 comtypes模块,如果其他方式安装,请自行安装comtypes模块 ...