Description

  沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛。此次联 赛共N支球队参加,比赛规则如下: 
    (1) 每两支球队之间踢一场比赛。 (2) 若平局,两支球队各得1分。 
    (3) 否则胜利的球队得3分,败者不得分。 
  尽管非常遗憾没有观赏到精彩的比赛,但沫沫通过新闻知道了每只球队的最后总得分, 然后聪明的她想计算出有多少种可能的比赛过程。 
  譬如有3支球队,每支球队最后均积3分,那么有两种可能的情况:
     可能性1          可能性2 
    球队  A  B  C  得分   球队 A  B  C  得分 
    A        -  3  0    3        A    -  0  3    3 
    B        0  -  3    3        B    3  -   0   3 
    C        3  0  -    3        C    0  3  -    3 
  但沫沫发现当球队较多时,计算工作量将非常大,所以这个任务就交给你了。请你计算 出可能的比赛过程的数目,由于答案可能很大,你只需要输出答案对109+7取模的结果

Input

  第一行是一个正整数N,表示一共有N支球队。 接下来一行N个非负整数,依次表示各队的最后总得分。

  输入保证20%的数据满足N≤4,40%的数据满足N≤6,60%的数据满足N≤8,100%的数据 满足3≤N≤10且至少存在一组解。

Output

  仅包含一个整数,表示答案对10^9+7取模的结果

Sample Input

4
4 3 6 4

Sample Output

3
 
 
题解:记忆化搜索。如果我们直接进行暴力搜索的话,会出现若干重复的情况,那么这个时候我们需要进行判重性剪枝,最直接的方式就是记录已经走过的状态。状态固然是当前每个队伍的得分,因为n<=10,但是即便这么小也不能直接存储,这里我们加一个long long的哈希来存储,开map进行判重。为什么这么暴力的办法是可行的?我们对状态数量进行一下分析就可以大胆使用了。10个队,对于每个队,最多比9场,得27分,那么放入hash函数中,最大为7.77*10^12,在long long范围内,用map存一下就行了。
  搜索的过程也是有讲究的。我们将每支队伍的得分从大到小排序,将得分多的队伍优先进行搜索,每次与当前得分最低的队伍进行匹配,这样可以很快搜完。
 
代码:
-----------------------------------------------------------------------------------------------------

#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;

#define MAXN 15
#define MOD 1000000007

typedef long long ll;

struct Cmp
{
  bool operator () (int a, int b)
  {
    return a > b;
  }
};
Cmp x;

ll a[MAXN];

map <ll, ll> mp;

ll hash(int o)
{
  ll res = o, tmp[MAXN];
  for (int i = 1; i <= o; i++) tmp[i] = a[i];
  sort(tmp + 1, tmp + o + 1, x);
  for (int i = 1; i <= o; i++) res += res * 28 + tmp[i];
  return res;
}

ll DFS(int o, int n)
{
  if (a[n] > 3 * (n - o)) return -1;
  ll res = 0;
  if (o == n)
  {
    if (n == 1) return 1;
    else
    {
      ll h = hash(n - 1);
      if (mp[h]) return mp[h];
      return mp[h] = DFS(1, n - 1);
    }
  }
  if (a[n] >= 3)
  {
    ll tmp = 0;
    a[n] -= 3, tmp = DFS(o + 1, n);
    if (tmp != -1) (res += tmp) %= MOD;
    a[n] += 3;
  }
  if (a[n] && a[o])
  {
    ll tmp = 0;
    a[n]--, a[o]--, tmp = DFS(o + 1, n);
    if (tmp != -1) (res += tmp) %= MOD;
    a[n]++, a[o]++;
  }
  if (a[o] >= 3)
  {
    ll tmp = 0;
    a[o] -= 3, tmp = DFS(o + 1, n);
    if (tmp != -1) (res += tmp) %= MOD;
    a[o] += 3;
  }
  return res ? res : -1;
}

int n;

int main()
{
  freopen("match.in", "r", stdin);
  freopen("match.out", "w", stdout);
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  sort(a + 1, a + n + 1, x);
  printf("%d", DFS(1, n));
  return 0;
}

-----------------------------------------------------------------------------------------------------

[BZOJ3139][HNOI2013] 比赛的更多相关文章

  1. BZOJ1306 [CQOI2009]match循环赛/BZOJ3139 [Hnoi2013]比赛[dfs剪枝+细节题]

    地址 看数据范围很明显的搜索题,暴力dfs是枚举按顺序每一场比赛的胜败情况到底,合法就累计.$O(3^{n*(n-1)/2})$.n到10的时候比较大,考虑剪枝. 本人比较菜所以关键性的剪枝没想出来, ...

  2. [BZOJ3139][HNOI2013]比赛(搜索)

    3139: [Hnoi2013]比赛 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1439  Solved: 719[Submit][Status] ...

  3. bzoj千题计划294:bzoj3139: [Hnoi2013]比赛

    http://www.lydsy.com/JudgeOnline/problem.php?id=3139 队伍的顺序不会影响结果 将队伍的得分情况作为状态,记忆化搜索 就是先搜索第一只队伍的得分情况, ...

  4. 【BZOJ3139】[HNOI2013]比赛(搜索)

    [BZOJ3139][HNOI2013]比赛(搜索) 题面 BZOJ 洛谷 题解 双倍经验

  5. [HNOI2013]比赛 (用Hash实现记忆化搜索)

    [HNOI2013]比赛 题目描述 沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛.此次联 赛共N支球队参加,比赛规则如下: (1) 每两支球队之间踢一场比赛. (2) 若平局, ...

  6. [HNOI2013]比赛 搜索

    [HNOI2013]比赛 搜索. LG传送门 直接暴力有60,考场上写的60,结果挂成40. 考虑在暴力的同时加个记忆化,把剩下的球队数和每支球队的得分情况hash一下,每次搜到还剩\(t\)个队的时 ...

  7. 【题解】HNOI2013比赛

    [题解][P3230 HNOI2013]比赛 将得分的序列化成样例给的那种表格,发现一行和一列是同时确定的.这个表格之前是正方形的,后来长宽都减去一,还是正方形.问题形式是递归的.这就启示我们可以把这 ...

  8. BZOJ3139/BZOJ1306 HNOI2013比赛/CQOI2009循环赛(搜索)

    搜索好难啊. 1.对于每个分数集合记忆化. 2.某人得分超过总分,剪枝. 3.某人之后全赢也无法达到总分,剪枝. 4.每有一场比赛分出胜负总分会多三分,而平局则会多两分.某人的分出胜负场次或平局场次超 ...

  9. 3139:[HNOI2013]比赛 - BZOJ

    题目描述 Description 沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛.此次联赛共N只队伍参加,比赛规则如下: (1) 每两支球队之间踢一场比赛. (2) 若平局,两支 ...

随机推荐

  1. [Unity] Shader(着色器)输入输出和语义

    在Unity5.x后, 已经支持了基于物理的光照模型,也就是常说的次时代引擎所必须具备的功能. 如果在Properties使用2D,CG里要用sampler2D,代表使用的是2维纹理 如果在Prope ...

  2. 1.0、Struts2的简单搭建方法

    一.Struts2:是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet:用于jsp页面与Java代码之间的交互. 1.核心:Filter拦截器,对所有的请求进行拦截. 2.工作 ...

  3. flash_header.S ( freescale imx6 board)

    /* * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. * * This program is free software; you ca ...

  4. [Hadoop] 在Ubuntu系统上一步步搭建Hadoop(单机模式)

    1 Hadoop的三种创建模式 单机模式操作是Hadoop的默认操作模式,当首次解压Hadoop的源码包时,Hadoop无法了解硬件安装环境,会保守地选择最小配置,即单机模式.该模式主要用于开发调试M ...

  5. CSS高效开发实战:CSS 3、LESS、SASS、Bootstrap、Foundation --读书笔记(1)设定背景图

    技术的新发展,除计算机可以接入互联网之外,平板电脑.智能手机.智能电视等其他设备均可访问互联网.在多设备时代,构建多屏体验也不是听说的那么难. 但是这也增加了学习CSS的难度?不知道如何上手,只懂一点 ...

  6. ASP.NET Core--基于授权的视图

    翻译如下: 开发人员通常希望基于当前用户身份显示,隐藏或以其他方式修改UI. 您可以通过依赖注入访问MVC视图中的授权服务. 将授权服务注入Razor视图,请使用@inject指令,例如: @inje ...

  7. Win10安装程序出现error code 2502 2503

    在Win10中,在安装msi安装包的时候常常会出现代码为2502.2503的错误.其实这种错误是由于安装权限不足造成的,可以这种msi的安装包不像其他exe的安装程序,在安装包上点击"右键& ...

  8. 如何有效地描述软件缺陷(Defect)?

    最近一个月偷懒了,刚看到一篇博文很不错.最近也是碰到一样的问题,由于我记录bug的描述不够清晰.导致开发看不懂我描述的bug,还有一些配置信息没记录好.出现一问三不知的情况,还被领导训.下面的博文是来 ...

  9. iOS整体框架类图

    Cocoa是OS X和iOS操作系统的程序的运行环境. iOS的操作系统层次结构分为四层:触摸UI层,媒体层,核心服务层,核心OS层.其中底层框架提供iOS的基本服务和技术,高层次框架简历在低层次框架 ...

  10. div自定义下拉框

    因为原生的下拉框不能修改其属性,很难美化下拉框. 所以自己用div简单自定义了一下下拉框,想美化直接修改css即可 <!DOCTYPE html> <html lang=" ...