bzoj1306[CQOI2009]match循环赛

bzoj1306[CQOI2009]match循环赛

题意:

n支队伍打单循环赛,赢的得3分,平局各得1分,输的不得分。已知n支队伍最终得分,求多少种可能的分数表。

题解:

爆搜,加入各种奇怪剪枝,比如:剩下的比赛全赢分数都不到要求就返回、当前分数超过了要求……还有一个重要的就是如果当前已经是最后一场就直接算出比赛结果,这个剪枝虽然表面上没什么用但实际上可以把程序从TLE的边缘拯救回来。这种题对我这种从不鸟常数的就是灾难。

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #define inc(i,j,k) for(int i=j;i<=k;i++)
 5 using namespace std;
 6 
 7 int s2[10],ans[10],tot,n,sz;
 8 void dfs(int x,int y,int z){
 9     if(z==sz){inc(i,1,n)if(s2[i]!=ans[i])return; tot++; return;}if(x>n||y>n)return;
10     if(y!=n||(y==n&&ans[x]-s2[x]==3)){
11         s2[x]+=3;
12         if(s2[x]+3*(n-y)>=ans[x]&&s2[y]+3*(n-x)>=ans[y]&&s2[x]<=ans[x]&&s2[y]<=ans[y])y==n?dfs(x+1,x+2,z+1):dfs(x,y+1,z+1);
13         s2[x]-=3;
14     }
15     if(y!=n||(y==n&&ans[x]-s2[x]==1)){
16         s2[x]++; s2[y]++;
17         if(s2[x]+3*(n-y)>=ans[x]&&s2[y]+3*(n-x)>=ans[y]&&s2[x]<=ans[x]&&s2[y]<=ans[y])y==n?dfs(x+1,x+2,z+1):dfs(x,y+1,z+1);
18         s2[x]--; s2[y]--;
19     }
20     if(ans[x]==s2[x]||y!=n){
21         s2[y]+=3;
22         if(s2[x]+3*(n-y)>=ans[x]&&s2[y]+3*(n-x)>=ans[y]&&s2[x]<=ans[x]&&s2[y]<=ans[y])y==n?dfs(x+1,x+2,z+1):dfs(x,y+1,z+1);
23         s2[y]-=3;
24     }
25 }
26 int main(){
27     scanf("%d",&n); inc(i,1,n)scanf("%d",&ans[i]);
28     memset(s2,0,sizeof(s2)); tot=0; sz=(n*n-n)>>1;
29     dfs(1,2,0); printf("%d",tot);
30 }

 

20160405

转载于:https://www.cnblogs.com/YuanZiming/p/5693114.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值