bzoj1306 [CQOI2009]match循环赛

来源:互联网 发布:淘宝新店手机号码采集 编辑:程序博客网 时间:2024/06/10 21:50

n支队伍进行循环赛,胜者得3分,平各得1分,负得0分.现给出各队伍最终分数,求可能符合的胜负情况数.(n<=8)

这个没法状压,只能爆搜了吧。。

主要剪枝有这几个:

某个队伍剩下全赢都达不到分数或已经超过分数剪枝.

当枚举到某个队伍的最后一场比赛时 可通过与结果的差值直接确定这一场情况

如果差3,1,0分就直接确定,差2分或3分以上直接剪枝。

差不多8s刚好卡过去。。

剪枝这个东西 真的就是玄学吧。。

#include<bits/stdc++.h>#define LL long long#define clr(x,i) memset(x,i,sizeof(x))using namespace std;const int N=10;int n,a[N],sc[N],st[4]={3,1,0,0},ans=0;void dfs(int u,int v){if( sc[u]>a[u] || sc[v]>a[v] )return;if(sc[u]+(n-v+1)*3<a[u])return;if(u==n){ans++;return;}if(v==n){int dt=a[u]-sc[u];if( dt==2 || dt>3 )return;sc[u]+=dt;sc[v]+=st[dt];dfs(u+1,u+2);sc[u]-=dt;sc[v]-=st[dt];}else{sc[u]+=3;dfs(u,v+1);sc[u]-=3;sc[v]+=3;dfs(u,v+1);sc[v]-=3;sc[u]+=1;sc[v]+=1;dfs(u,v+1);sc[u]-=1;sc[v]-=1;}}int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);dfs(1,2);printf("%d\n",ans);return 0;}




原创粉丝点击