【HNOI2013】比赛
来源:互联网 发布:h3c 查看端口聚合 编辑:程序博客网 时间:2024/05/18 03:37
题目
沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛。此次联赛共N 支球队参加,比赛规则如下:
(1) 每两支球队之间踢一场比赛。
(2) 若平局,两支球队各得1 分。
(3) 否则胜利的球队得3 分,败者不得分。
尽管非常遗憾没有观赏到精彩的比赛,但沫沫通过新闻知道了每只球队的最后总得分,然后聪明的她想计算出有多少种可能的比赛过程。
譬如有3 支球队,每支球队最后均积3 分,那么有两种可能的情况:
但沫沫发现当球队较多时,计算工作量将非常大,所以这个任务就交给你了。请你计算出可能的比赛过程的数目,由于答案可能很大,你只需要输出答案对10^9+7 取模的结果。
20%的数据满足N≤4;
40%的数据满足N≤6;
60%的数据满足N≤8;
100%的数据满足3≤N≤10且至少存在一组解。
分析
我们看到这题的条件,大概就能估计到这题的方向:搜索!
可是如何才能去优化这个搜索呢?
我们先写出一个比较简单的搜索,然后再剪枝!
dfs(x,a)表示我们已经打完1..x-1(及1..x-1中任意的i都和i+1..n打过一次了)
且状态为a,现在用a[0]去打x。
然后我们很明显的去枚举状态,然后转移就可以了。
其实这样的搜索已经是很优的了,但是这样搜我们会搜到很多重复的状态,怎么办呢?
哈希判重,把每次搜过的状态,直接加上它会产生的答案。
那么我们应该在什么时候才判重呢?
明显的,当确定了x,和a时后面的方案是可以确定的,所以我们从这个入手。
当然我们只能在打完了x的时候才去hash,而且有个优化,a数组转成数时要排一个序,否则这样状态数会很大。
这样便很好的解决这个问题了。
type arr=array[0..10] of longint;const mo=62304567;u=1000000007;var n,i,j:longint; a:array[0..10] of longint; c:array[0..10] of int64; ha:array[-1..mo,1..2] of longint;function hash(x:longint):longint;var k:longint;begin k:=x mod mo; while (ha[k,1]<>0)and(ha[k,1]<>x) do k:=(k+1)mod mo; exit(k);end;function get(a:arr):longint;var i:longint;p:int64;begin p:=a[0]; for i:=1 to n do for j:=i+1 to n do if a[i]>a[j] then begin a[0]:=a[i];a[i]:=a[j];a[j]:=a[0]; end; a[0]:=p; for i:=1 to n do p:=(p+a[i]*c[i])mod mo; exit(p);end;function dfs(x:longint;a:arr):longint;var i,o,p:longint;pe:boolean;begin dfs:=0; if a[a[0]]>(n-x+1)*3 then exit(0); if x>n then begin o:=get(a); p:=hash(o); if ha[p,1]<>0 then begin exit(ha[p,2]); end else begin if a[0]<>n-1 then begin if o=0 then o:=-1; ha[p,1]:=o;inc(a[0]);dfs:=(dfs+dfs(a[0]+1,a))mod u; ha[p,2]:=dfs; end else begin pe:=false; for i:=1 to n do if a[i]>0 then begin pe:=true;break;end; if not pe then begin ha[p,1]:=o;ha[p,2]:=1;exit(1); end else begin ha[p,1]:=o;ha[p,2]:=0;exit(0);end; end; end;exit; end; if a[a[0]]>=3 then begin dec(a[a[0]],3);dfs:=dfs+dfs(x+1,a);inc(a[a[0]],3);end; if a[x]>=3 then begin dec(a[x],3);dfs:=dfs+dfs(x+1,a);inc(a[x],3);end; if (a[x]>0)and(a[a[0]]>0) then begin dec(a[a[0]],1);dec(a[x],1);dfs:=dfs+dfs(x+1,a);inc(a[a[0]]);inc(a[x]);end;end;begin readln(n);c[0]:=1; for i:=1 to 10 do c[i]:=(c[i-1]*27)mod mo; for i:=1 to n do read(a[i]); for i:=1 to n do for j:=i+1 to n do if a[i]>a[j] then begin a[0]:=a[i];a[i]:=a[j];a[j]:=a[0]; end; a[0]:=1; writeln(dfs(2,a));end.
0 0
- [Hnoi2013]比赛
- HNOI2013 比赛
- 【HNOI2013】比赛
- [bzoj3139][HNOI2013]比赛
- bzoj3139: [Hnoi2013]比赛
- 【搜索】BZOJ3139 HNOI2013比赛
- 【搜索】BZOJ3139 HNOI2013比赛
- BZOJ 3139: [Hnoi2013]比赛
- BZOJ3139: [Hnoi2013]比赛
- 【bzoj3139】[Hnoi2013]比赛
- bzoj3139 [Hnoi2013]比赛
- 3139: [Hnoi2013]比赛
- BZOJ3139 HNOI2013比赛 (搜索)
- BZOJ 3139 [Hnoi2013]比赛 记忆化搜索
- hnoi2013
- [Hnoi2013]消毒
- 【HNOI2013】切糕
- 【HNOI2013】消毒
- 融云如何实现文件发送(高级进阶)
- 在web.xml中注册IntrospectorCleanupListener监听器以解决spring mvc等框架可能产生的内存泄露问题
- Java基础学习总结(33)——Java8 十大新特性详解
- freemarker生成word,表格分页
- WEB级HTTP请求内容的工具
- 【HNOI2013】比赛
- 【ZYNQ-7000开发之六】使用PS控制DDR3的读写
- powerdesigner odbc 表映射PDM
- leetcode -- Range Sum Query - Mutable -- 重点,有线段树
- 网站后台登录地址大全
- 千载难逢的大数据技术学习机会
- 【Linux 驱动】Netfilter/Iptables (七) 内核协议栈skb封装分析(续六)
- iOS 的VFL知识详解
- POJ2386——经典的DFS