1306: [CQOI2009]match循环赛

来源:互联网 发布:淘宝详情页视频下载 编辑:程序博客网 时间:2024/05/18 20:53

题目链接

题目大意:循环赛,给出所有队伍的最终得分,求方案数

题解:n只队伍共n*(n-1)/2场比赛,理论复杂度为28^3,显然不科学
玄学剪枝

1.若x的目前得分超过最终得分则剪枝
2.若x剩余比赛全胜也无法达到最终得分则剪枝
3.用最终得分-目前得分直接计算出x最后一场比赛的应得分,看上去没什么用,但是由于搜索树最后一层节点最多,实际效果不错

我的收获:剪枝大法

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int M=11;const int f[]={3,1,0,0};int n,result[M],has[M],str[M];int ans;void dfs(int x,int y){    if(has[x]>result[x]) return ;    if(has[x]+3*(n-y+1)<result[x]) return ;    if(x==n){ans++;return ;}    if(y==n)    {        int need=result[x]-has[x];        if(need==2) return ;        has[y]+=f[need];        dfs(x+1,str[x+1]);        has[y]-=f[need];    }     else{        has[x]+=3,dfs(x,y+1),has[x]-=3;        has[y]+=3,dfs(x,y+1),has[y]-=3;        has[x]+=1,has[y]+=1,dfs(x,y+1),has[x]-=1,has[y]-=1;    }}void work(){    dfs(1,str[1]);    cout<<ans<<endl;}void init(){    cin>>n;    for(int i=1;i<=n;i++) cin>>result[i];    for(int i=1;i<=n;i++) str[i]=i+1;}int main(){    init();    work();    return 0;} 
原创粉丝点击