比赛难度

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 817    Accepted Submission(s): 296

Problem Description
  最近,小明出了一些ACM编程题,决定在HDOJ举行一场公开赛。
  假设题目的数量一共是n道,这些题目的难度被评级为一个不超过1000的非负整数,并且一场比赛至少需要一个题,而这场比赛的难度,就是所有题目的难度之和,同时,我们认为一场比赛与本场题目的顺序无关,而且题目也不会重复。
  显而易见,很容易得到如下信息:
  假设比赛只用1个题目,有n种方案;
  假设比赛使用2个题目,有(n-1)*n/2种方案;
  假设比赛使用3个题目,有(n-2)*(n-1)*n/6种方案;
  ............
  假设比赛使用全部的n个题目,此时方案只有1种。
  
  经过简单估算,小明发现总方案数几乎是一个天文数字!
  为了简化问题,现在小明只想知道在所有的方案里面第m小的方案,它的比赛难度是多少呢?
 
Input
输入数据的第一行为一个整数T(1 <= T <= 20),表示有T组测试数据。
每组测试数据第一行为两个整数n, m(0 < n, m <= 10000),表示现在有n个题目,现在要求第m小的方案的比赛难度。接下来第二行有n个数字,分别表示这n个题目的难度值。
 
Output
对于每组测试数据,输出一行"Case #c: ans"(不包含引号),ans 表示要求的第m小的比赛难度,输入数据保证存在第m小的方案,具体参见样例。
 
Sample Input

2
5 6
1 1 1 1 1
5 25
1 2 3 4 5

 
Sample Output

Case #1: 2
Case #2: 11

 

 解题目报告

题目大意:

  有N个包含难度值的题目,每次比赛可以选若干个不同题目,则有C(N,1)+C(N,2)+...+C(N,N)种可能的题目组合的方案,每个方案的题目难度的总和则称为比赛难度。让你输出第M小的方案的比赛难度。

思路:

  如果只是考虑去计算所以方案的比赛方案的话,0<N<=10000,方案数有C(N,1)+C(N,2)+...+C(N,N),不可能枚举所以的方案数再去求第M小的方案的比赛难度。

不过,M的范围是限制在(0,10000]之间,也就是这题的突破口在在于直接求解第M小的数即可,也就是每次取出最小的那个方案的比赛难度,取M次即可、

  假如我们有N个题目,题目难度分别为X1,X2,X3...XN(Xi<=XJ,i<j)。

  我们可以很容易知道,比赛方案最小的比赛难度为X1,

  同样,也可以知道,比赛方案第二小的比赛难度为X2

  如果继续求解第三小的比赛难度,那第三小的是X1+X2,还是X3呢,

    如果,第三小的是X3,那么第四小的是X1+X2,还是X4呢。

    如果,第三小的是X1+X2,那么第四小的是X1+X3,还是X3呢?

  

  对于求最小值或者最大值的问题,我们可以用优先队列来求解,但如何求解也在于你如何构造一个合理的结构体来实现、

  首先,我们要构造的这个结构体,肯定是要来记录某一个方案的比赛难度的总和、

  然后,我们可以确定的是第一小的方案的比赛难度,但是如何实现记录每一个方案的比赛难度呢?

  我们先把所有题目的比赛的难度都先排好序,从小到大依次拿题目,便能保证你下一个方案的比赛难度是递增的。

  我们保证,第一次拿出来的结构体(方案)是最小的,然后在第一次那结构体(方案)的基础上,放入比它大的其他方案(结构体),这样,每次同样的操作,便可以实现在第M次拿出第M小的方案的比赛难度。

  我们要实现每个方案前后是有关联的,也就是说我们需要构建的结构体也是需要能够关联到前后方案的。

  我们在结构体里面,定义一个Sum,用来记录之前方案的比赛难度的总和。(前关联)

  然后在定义一个ID,则是表示当前加入的方案的题目难度。(后关联)

  每一个结构体表示的方案的比赛难度则是=Sum+Num[ID];

 struct Node
{ //每一个结构体表示一种题目难度总和=Sum+Num[ID];
int Sum;//记录之前题目难度的总和,
int ID;//记录下一个题目的难度
friend bool operator <(Node a,Node b){
return a.Sum+Num[a.ID]>b.Sum+Num[b.ID];
}//把题目难度总和比较小的优先
};

需要构建的合理的结构体

  构建完结构体,还有很重要的一点是,如何正确放入下一个方案?

  我们可以知道,对于当前方案的话,比赛的难度为Sum+Num[ID],那么,比他大的方案有也就只有Sum+Num[ID+1]。(更新下标值)

  而且,你还需要更新下一个方案的比赛难度的总和,也就是(Sum+Num[ID])+Num[ID+1]。(更新方案的比赛难度总和)

  用优先队列维护最小值,每次取出最小值在进行更新便可以得出第M小的方案的比赛难度、

  PS:对放入(Sum+Num[ID])+Num[ID+1]还是不太理解的话,可以想想,虽然Sum+Num[ID+1]肯定小于(Sum+Num[ID])+Num[ID+1],

  但你无法确定,你的下下一个方案也就是Sum+Num[ID+1]+Num[ID+2]是否会比(Sum+Num[ID])+Num[ID+1]小?

  这样, 也才能够把所有方案从小到大都放入优先队列中,在不懂的就自己去画画图就大概知道为什么了、

  

 #include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
int Num[];//Num[i],记录第i个题目的难度
struct Node
{ //每一个结构体表示一种题目难度总和=Sum+Num[ID];
int Sum;//记录之前题目难度的总和,
int ID;//记录下一个题目的难度
friend bool operator <(Node a,Node b){
return a.Sum+Num[a.ID]>b.Sum+Num[b.ID];
}//把题目难度总和比较小的优先
};
int main()
{
int T,N,M,i,t=;
Node TMD;
scanf("%d",&T);
while(T--){
priority_queue<Node>q;
scanf("%d%d",&N,&M);
for(i=;i<N;i++){
scanf("%d",&Num[i]);
}
sort(Num,Num+N);//将题目难度小的排在前面
TMD.Sum=;//初始状态,题目难度为0
TMD.ID=;//默认从最小的开始
q.push(TMD);
printf("Case #%d: ",t++);
while(M--){
TMD=q.top();q.pop();
if(M==){//输出第M小的题目难度总和
printf("%d\n",TMD.Sum+Num[TMD.ID]);
}
if(++TMD.ID<N){
q.push(TMD);//更新的下标值的
TMD.Sum+=Num[TMD.ID-];
q.push(TMD);//更新下标值以及总和
}
}
}
return ;
}

【优先队列】-HDU4546比赛难度的更多相关文章

  1. 比赛难度(HDU4546)

    比赛难度 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submis ...

  2. UVa 11134 - Fabled Rooks 优先队列,贪心 难度: 0

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  3. COJ 0503 比赛

    比赛 难度级别:D: 运行时间限制:2000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 初三年级举办了一场篮球赛,共有N个班级参加.当WZJ知道了这件事情, 已经 ...

  4. DataFoundation比赛总结

    2018.3.20号左右,因为研究生的数据挖掘课程的老师要求我们集体参加一个比赛 ,所以在比赛参与时间.比赛难度和比赛类型的几种条件下,我们选择了2018平安产险数据建模大赛-驾驶行为预测驾驶风险比赛 ...

  5. NOIP2015跳石头[二分答案]

    题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选 择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N 块岩石( ...

  6. [NOIP2015] 提高组 洛谷P2678 跳石头

    题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N 块岩石(不 ...

  7. NOIP2015 跳石头

    一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N块岩石(不含起点和终点的岩石). ...

  8. 【NOIP2015】提高day2解题报告

    题目: P1981跳石头 描述 一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N ...

  9. NOIP 2015复赛提高组Day2 T1==Codevs 4768 跳石头

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold  题目描述 Description 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中 ...

随机推荐

  1. MongoDB应用介绍之前

    MongoDb企业应用实战(一) 写在MongoDB应用介绍之前   故事背景: 本人有幸,经老友( 现为x知名快递公司技术总监 ) 推荐进入中国前三大民营快递公司之一工作,在此非常感谢他,在此也非常 ...

  2. oracle数据库对date字段类型存在空值进行排序的处理方法

    oracle数据库对date字段类型存在空值进行排序的处理方法      oracle 数据库,如果表中有一个字段类型为date,且该字段类型存在空值,并且需要排序,     解决方法为使用oracl ...

  3. ACM STUDY

    ACM学习<二>   穷举算法思想:     一句话:就是从所有可能的情况,搜索出正确的答案. 步骤:     1.对于一种可能的情况,计算其结果.     2.判断结果是否满足,YES计 ...

  4. CSS sprites减少HTTP请求

    使用CSS sprites减少HTTP请求   sprites是鬼怪,小妖精,调皮鬼的意思,初听这个高端洋气的名字我被震慑住了,一步步掀开其面纱后发觉很简单的东西,作用却很大 神马是CSS 小妖精 C ...

  5. iOS: JS和Native交互的两种方法

    背景: UIWebView: iOS 用来展示 web 端内容的控件. 1. 核心方法: - (NSString*)stringByEvaluatingJavaScriptFromString:(NS ...

  6. 圆形头像以及一些常见需求形状自定义ImageView组件

    在实际开发中,我们经常会遇到这样的需求,就是无论图片长啥样,我们都要其显示成圆形.圆形加一个边框.矩形加边框,带圆角的矩形等等,lib和demo下载地址:https://github.com/mapl ...

  7. 用TableView做的新闻客户端展示页面

    用TableView做的新闻客户端展示页面 //  MyTableViewImageCell.m //  SildToDo // //  Created by WildCat on 13-8-18. ...

  8. 什么是DCI

    目录 备注什么是DCI?如何将Role注入到Data中?开发期注入字节码增强MixinTraitTemplateT4 + 部分类 + 显式接口实现 + 扩展类型,C#专用运行期注入Mixin动态代理为 ...

  9. jQuery获取动态生成的元素

    需求描述:页面上可以动态添加数据,比如table,点击按钮可以动态添加行.又或页面 加载时table数据是通过ajax从后台获取的.而这时我们想要获取其中的某个值,又该如何获取呢? 如果是要通过某个事 ...

  10. D3DXCreateTextureFromFileInMemoryEx函数

    注:限于翻译水平限制,详情请查阅MSDN D3DXCreateTextureFromFileInMemoryEx 函数 从内存文件创建一个纹理,这是个比D3DXCreateTextureFromFil ...