目录

  • 题意
  • 输入格式
  • 输出格式
  • 样例
    • Input
    • Output
  • 数据范围
  • 时间限制
  • 思路
  • 代码

题意

有\(N\)个人,现在你要从中选出\(K\)个人出来,然后让这\(K\)个人一起参加\(K\)场比赛。其中,每个人都要参加所有的比赛。

定义其中一场比赛的得分为这\(K\)个人的得分的最大值。然后定义这个队的得分为\(K\)场比赛的得分的加和。

例如,\(K=3\)时,有一支3个人的队伍,一共打3场比赛。第1个人在3场比赛中的得分分别为\((4, 5, 3)\),第2个人在3场比赛中的得分分别为 \((7, 3, 6)\), 第3个人在3场比赛中的得分分别为 \((3, 4, 5)\)。那么这个队伍的总得分就是\(7+5+6=18\)。

现在你要求出的是,总分最第\(C\)大的队伍的得分是多少。定义两个队伍不同,当且仅当存在两个两个队伍的人的编号不同。

输入格式

第一行3个整数分别表示\(N,K,C\);
接下来N行,每行K个整数,表示每个人在每场比赛中的得分。

输出格式

一行,输出得分第\(C\)大的队伍的得分。

样例

Input

5 4 4
7 0 4 9
3 0 8 4
1 1 3 7
5 1 3 4
4 2 2 9

Output

24

数据范围

1.(13 points) 1 ≤ N ≤ 500, 1 ≤ K ≤ 2, 1 ≤ C ≤ 2 000.
2.(31 points) 1 ≤ N ≤ 40, 1 ≤ K ≤ 6, 1 ≤ C ≤ 2 000.
3.(24 points) 1 ≤ N ≤ 500, 1 ≤ K ≤ 6, 1 ≤ C ≤ 2 000, 每个人的分数大小不超过10.
4.(32 points) 1 ≤ N ≤ 500, 1 ≤ K ≤ 6, 1 ≤ C ≤ 2 000.

时间限制

\(2\ sec / 30\ sec\)

思路

首先声明这是自己的方法,没有看官方题解...

首先求一个得分最大的队伍出来,怎么求呢?
就是让每一场比赛的得分都尽量大,也就是取所有人中这场比赛得分最大的那个人。然后这样子选完之后可能没有选齐K个人,那么剩余的位置就随便找人来补齐就好了。

然后仿照所有的求第k大的题目的做法,把这个队伍塞到一个大根堆(priority_queue)中去,每次都从队首取出一个当前的最大答案,然后用这个队伍进行拓展,塞入其它没有出现过的其他队伍。

如何拓展呢?
最暴力的想法是,每次都将这个队伍中的一个人换成另外一个人,然后在确定了这支新的队伍没有出现过之后,就将这支队伍也塞到优先队列中去。

如何判断之前是否重复呢?我用的是Hash,然后把Hash值塞到一个set里面去,就可以简单的判重了。

考虑一下时间复杂度:一共要取出C次,就是\(O(C)\),每次都要枚举将哪个人替换掉,也就是\(O(K)\)。还要枚举替换成哪个人,也就是\(O(N)\)。替换了之后,还要算出新的队伍的得分是多少,也就是\(O(K^2)\)的。然后还有set和priority_queue的时间复杂度,设为\(Const\)。那么总的时间复杂度就是\(O(N*K^3*C*Const)\),大概有\(216,000,000+\),好像跑不过...

考虑剪枝。考虑替换一个人的时候,只在N个人当中选出那些替换之后会使得答案变小或不变的那些人进行判重,判断没有出现过之后再选取其中的最大值进行扩展。这样子总共扩展出来的节点数就有原来的\(C*K*N\)变为了\(C*K\),优先队列和set部分的时间就变小了。然后枚举的时候,也被剪掉了不少。这样子就可以跑到0.3s~0.4s左右。

代码

实现的有点丑,但是算法还是很简单暴力的。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define MAXN 500
#define MAXK 6
#define MAXC 2000
#define MO 10000007
using namespace std;
typedef long long LL;
struct state
{int val;LL st;state(){};state(int _val,LL _st):val(_val),st(_st){};
};
bool operator < (const state &A,const state &B){return A.val<B.val;}
priority_queue<state> que;
struct node
{LL x;node *nxt;
}nd[MAXC*MAXN*MAXK+5];
node *ncnt=&nd[0],*Adj[MO+5];
int n,k,c,tmp[MAXK+1];
int scr[MAXN+5][MAXK+1];
LL Encode(int *seq)
{LL ret=0;for(int i=1;i<=k;i++)ret=1LL*ret*n+(1LL*seq[i]-1);return ret;
}
void Decode(LL val,int *seq)
{for(int i=k;i>=1;i--)seq[i]=val%n+1,val/=n;
}
int GetVal(int *seq)
{int ret=0;for(int j=1;j<=k;j++){int mxval=0;for(int i=1;i<=k;i++)mxval=max(mxval,scr[seq[i]][j]);ret+=mxval;}return ret;
}
void Print(int *seq)
{for(int i=1;i<=k;i++)printf("%d ",seq[i]);printf("\n");
}
void Insert(LL x)
{int id=x%MO;node *p=++ncnt;p->x=x;p->nxt=Adj[id];Adj[id]=p;
}
bool Find(LL x)
{int id=x%MO;for(node *p=Adj[id];p!=NULL;p=p->nxt)if(p->x==x)return true;return false;
}
int Solve()
{static int tmp1[MAXK+5],tmp2[MAXK+5];static bool sp[MAXN+5];state fro;for(int tmn=1;tmn<c;tmn++){fro=que.top();que.pop();Decode(fro.st,tmp1);for(int i=1;i<=k;i++)sp[tmp1[i]]=1;for(int i=1;i<=k;i++){LL mxst;int mxval=-1;for(int j=1;j<=n;j++)if(sp[j]==false){for(int p=1;p<=k;p++)tmp2[p]=tmp1[p];tmp2[i]=j;int val=GetVal(tmp2);if(val>fro.val) continue;if(val>mxval){sort(tmp2+1,tmp2+1+k);LL st=Encode(tmp2);if(Find(st))continue;mxval=val,mxst=st;}}if(mxval==-1)continue;Insert(mxst);Decode(mxst,tmp2);que.push(state(mxval,mxst));}for(int i=1;i<=k;i++)sp[tmp1[i]]=0;}return que.top().val;
}
int main()
{freopen("olymp.in","r",stdin);freopen("olymp.out","w",stdout);scanf("%d %d %d",&n,&k,&c);for(int i=1;i<=n;i++)for(int j=1;j<=k;j++)scanf("%d",&scr[i][j]);for(int j=1;j<=k;j++){int mxpos=-1;for(int i=1;i<=n;i++)if(mxpos==-1||scr[mxpos][j]<scr[i][j])mxpos=i;tmp[j]=mxpos;}sort(tmp+1,tmp+1+k);int len=unique(tmp+1,tmp+1+k)-tmp-1;for(int i=len+1;i<=k;i++)for(int j=1;j<=n;j++){bool Find=false;for(int p=1;p<i&&Find==false;p++)if(tmp[p]==j)Find=true;if(Find==false){tmp[i]=j;break;}}sort(tmp+1,tmp+1+k);LL ret=Encode(tmp);Insert(ret);que.push(state(GetVal(tmp),ret));int ans=Solve();printf("%d\n",ans);return 0;
}
/*
5 4 4
7 0 4 9
3 0 8 4
1 1 3 7
5 1 3 4
4 2 2 9*/

转载于:https://www.cnblogs.com/T-Y-P-E/p/11046377.html

[BOI2019][第K大问题][暴力剪枝]D2T1 Olympiads相关推荐

  1. [NBUT 1458 Teemo]区间第k大问题,划分树

    裸的区间第k大问题,划分树搞起. #pragma comment(linker, "/STACK:10240000") #include <map> #include ...

  2. UVA 10074 Take the Land dp/暴力+剪枝

    原题传送门:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...

  3. CodeForces 1138B暴力+剪枝

    [题目链接]Circus [题目分析]理解题意以后发现并没有什么思路,没有什么算法能用,这个时候就应该想到计算机解题的本质--暴力求解.相应的就要想到剪枝的条件,肯定不能盲目的暴力求解. 总共有四种人 ...

  4. WC2015 k小割(k短路+暴力+搜索)

    首先这道题不是非同一般的恶心,三个数据层次对应三个程序= = PROBLEM:http://uoj.ac/problems 解法: 1~2直接暴力枚举边的选择与否+判断就行了 7~14可以发现是一个平 ...

  5. 【NOIP模拟题】【DP】【同余最短路】【暴力剪枝】2016.11.15 第二题 小L的牛栏 题解

    小L的牛栏 [题目描述] 小L通过泥萌的帮助,成功解决了二叉树的修改问题,并因此写了一篇论文, 成功报送了叉院(羡慕不?).勤奋又勤思的他在研究生时期成功转系,考入了北京大学光华管理学院!毕业后,凭着 ...

  6. KY16 求root(N, k)|模拟暴力解法

    模拟暴力解法失败,这个方法正确是正确的,但是提交的时候会运行超时 #include <stdio.h> #include <iostream> #pragma warning( ...

  7. 整数无序数组求第K大数(暴力|快排) - 滴滴出行2018校园招聘内推笔试-研发工程师

    时间限制:1S 空间限制:32768K 题目描述: 给定无序整数序列,求第K大的数,例如{45,67,33,21},第2大的数为45 输入描述: 输入第一行为整数序列,数字用空格分割,如:45 67 ...

  8. URAL 1200 - Horns and Hoofs(暴力+剪枝)

    比赛时水过的,现在贴一下正规做法. #include <cstdio> #include <cstring> #include <cstdlib> #include ...

  9. 2021CCPC桂林游记

    写在前面 关于我大学两年打了7场正式赛其中6场是线上的事 -2 Week 10月份最早得知ccpc桂林要办线下,估摸着就剩桂林可能是线下了,就算顶着一众强队报名也冲了,不去博弈什么了. 10月22日晚 ...

最新文章

  1. 南京超过广州!4 月程序员工资统计出炉,平均 14596 元
  2. 2012年A股可能再跌20%~30%
  3. sqlite 增删改查附代码
  4. 《应试教育洗礼的“好”学生的学习行为特征分析》 2019-11-02
  5. 弹出确定_Redmi K30 Pro再剧透:弹出式全面屏,没有高刷
  6. vue点击input框出现弹窗_vue组件实现弹出框点击显示隐藏效果
  7. [HDU]1723Distribute Message
  8. 【报告分享】面向数据流的产品迭代及业务闭环.pdf
  9. Qt4_IconEditor窗口部件
  10. debian 安装 php,Ubuntu/Debian上安装Nginx+php环境详细教程
  11. 语言软件生成outsid_常用的C语言开发工具有哪些
  12. 【编译原理笔记04】语法分析:自顶向下的分析概述、文法转换、LL1文法
  13. 用python画多来a梦-使用Python的Turtle绘制哆啦A梦实例
  14. 在Java中将字符串转换为日期,将日期转换为字符串
  15. select框多级联动
  16. winform 图片压缩大小为原图的一半_图片压缩指定大小?!这款神奇的工具有必要了解一下...
  17. java调阿里云短信接口
  18. 红米手机使用应用沙盒一键修改cpu信息
  19. 计算机程序可以通过删除卸载嘛,怎么彻底卸载电脑软件程序多种方法
  20. C语言练习,指针变量作函数参数,从键盘输入一个m行n列的二维数组,然后计算数组中元素的最大值及其所在的行列下标值。其中,m和n的值由用户键盘输入。已知m和n的值都不超过10

热门文章

  1. .sql文件如何执行_Excel如何运行可执行文件,别急,用过vba Shell函数的都知道
  2. Android简单手势滑动的识别
  3. ECMAScript6入门教程(一)
  4. iTerm2 的配置与美化
  5. 2007年9月c语言真题及答案,2007年9月二级C语言笔试真题和答案(已再修改).doc
  6. java代码统计收藏量_干货收藏 | 35个Java 代码性能优化总结(上)
  7. java里面赋值运算符解释_java复合赋值运算符和赋值运算符
  8. 这几个juniper巡检命令超实用
  9. Kubernetes 新玩法:在 yaml 中编程
  10. Linux系统用户环境变量大全,linux系统和用户环境变量的配置文件