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

看完题目后看到数据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. Cesium学习笔记(五):3D 模型 (http://blog.csdn.net/umgsoil/article/details/74572877)

    Cesium支持3D模型,包括关键帧动画,皮肤的改变还有单个节点的选择等,Cesium还提供了了一个基于网络的工具,将COLLADA模型转换为glTF,方便和优化模型添加 还记得我们在实体添加的时候添 ...

  2. dva相关文档

    https://dvajs.com/guide/getting-started.html#%E5%AE%9A%E4%B9%89-model-------dva.js https://dvajs.com ...

  3. js 简单模板引擎

    代码 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" cont ...

  4. enote笔记语言(3)

    what&why(why not)&how&when&where&which:紫色,象征着神秘而又潜蕴着强大的力量,故取紫色. key&key-memo ...

  5. 几校联考——day1题解

    T1 约数的个数(好像不可提交) 如果一个整数a能够整除整数b,那么a叫做b的约数.现在有N(1 <= N <= 100,000)个整数,对于其中的每一个数,请找出它在其余N - 1个整数 ...

  6. 2018.03.04 晚上Atcoder比赛

    C - March Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement There are N  ...

  7. [luogu4728 HNOI2009] 双递增序列 (dp)

    传送门 Solution 前几天刚做了类似题,这种将一个序列拆分为两个单调序列的题一般都是设\(dp[i]\)表示i为一个单调序列的末尾时,另一个序列的末尾是多少 然后应用贪心的思想,在这道题中就是让 ...

  8. 51.percentiles rank以及网站访问时延SLA统计

    主要知识点: percentile_ranks的用法 percentile的优化     一.percentile_ranks的用法 SLA:就是所提供的服务的标准. 比如一个网站的提供的访问延时的S ...

  9. node.js开发环境配置

    node.js是什么 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效.Node.j ...

  10. Huawei-R&S-网络工程师实验笔记20190609-VLAN划分综合(Hybrid端口)

    >Huawei-R&S-网络工程师实验笔记20190609-VLAN划分综合(Hybrid端口) >>实验开始,先上拓扑图参考: >>>实验目标:分别实现主 ...