预先警告:我的做法代码量比较大

看完题目后看到数据n<=8,

不难想到这题可以写深搜来做

分析

比如说以数据:

3
3 3 3

为例子,

进行了三场比赛:AB AC BC;

我们只要搜索每场比赛,并枚举比赛的三个结果(胜、负、平)并判断能否达到答案的分数即可

如果是三个人:

void dfs(int step) {
if(step==cs+1){
int ff=1;
for(int i=1;i<=n;i++)
if(a[i]!=s[i]) ff=0;
if(ff)
ans++;
return;
}
int x=team3[step][0],y=team3[step][1];//team数组记录了每场比赛的两个参与者
if(s[x]+3<=a[x]){//结局1 A胜
s[x]+=3;
dfs3(step+1);
s[x]-=3;//回溯
}
if(s[y]+3<=a[y]){////结局2 B胜
s[y]+=3;
dfs3(step+1);
s[y]-=3;
}
if(s[x]+1<=a[x]&&s[y]+1<=a[y]){//结局3 平
s[x]++;
s[y]++;
dfs3(step+1);
s[y]--;
s[x]--;
}
}

这样搜索的初步就算完成了

然而分析一下时间复杂度

由于我们搜索的是每一局比赛,每个比赛有三种结果,最多可能有(8*7/2)28场比赛,那么当n8时,时间复杂度为O(3^28(≈2.2e13)) 若不加剪枝肯定会T;

所以要加上一些剪枝

因为要求方案数,那么肯定最优化剪枝不行

排序?似乎对本题求解没什么帮助

而可行性剪枝在这里可以发挥出作用

如果某个人在这局比赛后每次都赢,但是最终得分仍然低于期望得分,那么这个情况不存在,直接return

还是以三个人为例

上面的代码可以改成这样子:

void dfs(int step) {
if(step==cs+1){
int ff=1;
for(int i=1;i<=n;i++)
if(a[i]!=s[i]) ff=0;
if(ff)
ans++;
return;
} for(int i=1;i<=n;i++){//剪枝
if(jz[n][i][step+1]*3+s[i]<a[i])//jz数组记录了总共n个人时第step场比赛后,还有几局比赛的机会(即胜利的可能)
return;
} int x=team3[step][0],y=team3[step][1];
if(s[x]+3<=a[x]){
s[x]+=3;
dfs3(step+1);
s[x]-=3;
}
if(s[y]+3<=a[y]){
s[y]+=3;
dfs3(step+1);
s[y]-=3;
}
if(s[x]+1<=a[x]&&s[y]+1<=a[y]){
s[x]++;
s[y]++;
dfs3(step+1);
s[y]--;
s[x]--;
} }

其他的细节比如当n2||n1时可以直接输出

还有team数组(可以再写一个test程序直接输出,不用手打):

int team8[50][2]={{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{3,4},{3,5},{3,6},{3,7},{3,8},{4,5},{4,6},{4,7},{4,8},{5,6},{5,7},{5,8},{6,7},{6,8},{7,8}};
int team7[50][2]={{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{2,3},{2,4},{2,5},{2,6},{2,7},{3,4},{3,5},{3,6},{3,7},{4,5},{4,6},{4,7},{5,6},{5,7},{6,7}};
int team6[50][2]={{1,2},{1,3},{1,4},{1,5},{1,6},{2,3},{2,4},{2,5},{2,6},{3,4},{3,5},{3,6},{4,5},{4,6},{5,6}};
int team5[50][2]={{1,2},{1,3},{1,4},{1,5},{2,3},{2,4},{2,5},{3,4},{3,5},{4,5}};
int team4[50][2]={{1,2},{1,3},{1,4},{2,3},{2,4},{3,4}};
int team3[50][2]={{1,2},{1,3},{2,3}};

这样大概...就可以AC了吧

【BZOJ1306】match循环赛的更多相关文章

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

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

  2. BZOJ1306: [CQOI2009]match循环赛

    [传送门:BZOJ1306] 简要题意: 有n个队伍,每个队伍都要和其他队伍比一场,赢了的队得3分,输了的队不得分,打平两队各得一分,给出每个队伍的得分,求出对战方案数 题解: DFS暴搜!!一眼就觉 ...

  3. [BZOJ1306] [CQOI2009] match循环赛 (搜索)

    Description Input 第一行包含一个正整数n,队伍的个数.第二行包含n个非负整数,即每支队伍的得分. Output 输出仅一行,即可能的分数表数目.保证至少存在一个可能的分数表. Sam ...

  4. 【搜索】【剪枝】bzoj1306 [CQOI2009]match循环赛

    dfs+剪枝*4(通过得很勉强): 1.只枚举一半的比赛,另一半直接得出. 2.处理前缀和,若大于目标得分则剪枝 3.前缀和加上若接下来全胜的得分 仍小于 目标得分,则剪枝. 4.枚举到每个人的最后一 ...

  5. bzoj1306: [CQOI2009]match循环赛(模拟爆搜)

    Input第一行包含一个正整数n,队伍的个数.第二行包含n个非负整数,即每支队伍的得分.Output输出仅一行,即可能的分数表数目.保证至少存在一个可能的分数表.Sample Input 6 5 6 ...

  6. bzoj 1306: [CQOI2009]match循环赛【dfs+剪枝】

    大力剪枝,最后洛谷上还开了o2才过-- 大概这样剪枝: 1.搜索中,一个队当前得分超过要求或者一个队剩下的比赛场数全赢也达不到要求则return: 2.注意到如果平局,最总分的贡献是2,否则是3,所以 ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. 【BZOJ1306】[CQOI2009]循环赛(搜索)

    [BZOJ1306][CQOI2009]循环赛(搜索) 题面 BZOJ 洛谷 题解 爆搜一下,\(hash\)记录是否已经考虑过这个状态,记忆化解决问题. #include<iostream&g ...

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

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

随机推荐

  1. /etc目录常用配置文件

    /etc/resolv.conf DNS客户端配置文件,逐渐被网卡配置文件所替代 /etc/hosts 本机DNS解析文件,优先级高于DNS服务器 /etc/hostname CentOS 7 主机名 ...

  2. linux虚拟主机的三种方法

    虚拟主机虚拟主机是将一台(或者一组)服务器的资源(系统资源.网络带宽.存储空间等)按照一定的比例分割成若干相对独立的“小主机”的技术.每一台这样的“小主机”在功能上都可以实现WWW.FTP.Mail等 ...

  3. js 弹出div窗口 可移动 可关闭

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  4. models中,对于(Small)IntegerField类型字段的choices参数在前端的展示

    # models.py class UserInfo(models.Model): gender_choices = ( (1, "男"), (2, "女"), ...

  5. Vue动态组件&异步组件

    在动态组件上使用keep-alive 我们之前曾经在一个多标签的界面中使用is特性来切换不同的组件: Vue.js的动态组件模板 <component v-bind:is="curre ...

  6. python - 函数的定义和使用

    目录 函数的定义和使用 一. 为什么要用函数? 二. 函数的参数 三. 函数的变量 global和nolocal 四. 递归函数 五. lamabda匿名函数 函数的定义和使用 1 def test( ...

  7. Python基础-判断类型统计个数

    写函数,计算传入字符串中[数字].[字母].[空格] 以及 [其他]的个数 首先我们定义四个变量,分别存储数字.字母.空格.其他的数量 digital_temp = 0 # 存储数字个数 letter ...

  8. LA 4329 Ping pong

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; ; ; ...

  9. 【codeforces 785E】Anton and Permutation

    [题目链接]:http://codeforces.com/problemset/problem/785/E [题意] 给你一个初始序列1..n顺序 然后每次让你交换任意两个位置上面的数字; 让你实时输 ...

  10. UVALIVE 6958 Indoorienteering

    题目大意:有不超过14个点组成的完全图,给出邻接矩阵,问是否存在长度为W的欧拉回路? 数据范围:n<=14, w<=1e15: standard input/output 7 s, 256 ...