zoukankan      html  css  js  c++  java
  • bzoj 3139: [Hnoi2013]比赛

    Description

    沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛。此次联 赛共N支球队参加,比赛规则如下:
    (1) 每两支球队之间踢一场比赛。 (2) 若平局,两支球队各得1分。
    (3) 否则胜利的球队得3分,败者不得分。
    尽管非常遗憾没有观赏到精彩的比赛,但沫沫通过新闻知道了每只球队的最后总得分, 然后聪明的她想计算出有多少种可能的比赛过程。
    譬如有3支球队,每支球队最后均积3分,那么有两种可能的情况:
     可能性1    可能性2
    球队  A  B  C  得分   球队 A  B  C  得分
    A        -  3  0  3             A     -  0  3  3
    B        0  -  3  3             B    3  -  0  3
    C        3  0  -  3            C    0  3  -  3
    但沫沫发现当球队较多时,计算工作量将非常大,所以这个任务就交给你了。请你计算 出可能的比赛过程的数目,由于答案可能很大,你只需要输出答案对109+7取模的结果

    Input

    第一行是一个正整数N,表示一共有N支球队。接下来一行N个非负整数,依次表示各队的最后总得分。

    输入保证20%的数据满足N≤440%的数据满足N≤660%的数据满足N≤8100%的数据满足3≤N≤10且至少存在一组解。

    Output

    仅包含一个整数,表示答案对10^9+7取模的结果

    Sample Input

    4
    4 3 6 4

    Sample Output

    3

    HINT

    Source

    鬼里鬼气的搜索题,傻逼爆搜就是枚举每场比赛的结果,考虑分数状态有大量重复,考虑用记忆化搜索;

    每个人的得分最大27,只有10个人,所以用ll的哈希记录状态用map来判重;

    用f[i][S],表示从第i个人开始搜,分数状态为S的方案数;

    然后依旧是枚举每个人和他后面的人比赛,有一个剪枝if(3*(r-l+1)<a[i])就是不合法,然后我们从剩余分数小的开始和别人比赛,这样会肯定更快搜完;

    我们在搜完一个人的时候就把后面的状态sort一遍再继续搜下一个人,这样不会影响结果,而且排序后会更快搜完;

    话说这是cqoi的原题,堂堂HN竟然考他省原题,还没有加强。。。

    //MADE BY QT666
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int N=100050;
    const int mod=1e9+7;
    map<ll,ll> bj[N],f[N];
    int n;
    ll gethsh(int *a){
        ll ret=1;
        for(int i=1;i<=n;i++) ret=ret*29+a[i];
        return ret;
    }
    int dfs(int *a,int l,int r){
        if(l>=r){
    	if(a[l]) return 0;
    	if(l==n) return 1;
    	int b[15];
    	for(int i=1;i<=n;i++) b[i]=a[i];
    	sort(b+1+l,b+1+n);ll hsh=gethsh(b);
    	if(bj[l+1][hsh]) return f[l+1][hsh];
    	f[l+1][hsh]=dfs(b,l+1,n);
    	bj[l+1][hsh]=1;
    	return f[l+1][hsh];
        }
        if(3*(r-l+1)<a[l]) return 0;
        int tot=0;
        if(a[l]>=3){
    	a[l]-=3;
    	tot+=dfs(a,l,r-1);tot%=mod;
    	a[l]+=3;
        }
        if(a[l]>=1&&a[r]>=1){
    	a[l]--,a[r]--;
    	tot+=dfs(a,l,r-1);tot%=mod;
    	a[l]++;a[r]++;
        }
        if(a[r]>=3){
    	a[r]-=3;
    	tot+=dfs(a,l,r-1);tot%=mod;
    	a[r]+=3;
        }
        return tot;
    }
    int a[N];
    int main(){
        //freopen("match.in","r",stdin);
        //freopen("match.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        int ans=dfs(a,1,n);
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    SOA架构之限流
    《OD面试》之多线程高并发
    认知升级之第一性原理
    我的第一性原理
    书单收集
    mysql死锁问题解决
    阿里巴巴未来十年使命、愿景和价值观
    python操作Excel模块openpyxl
    qt5--文件操作
    qt5--QPainter绘图
  • 原文地址:https://www.cnblogs.com/qt666/p/7653272.html
Copyright © 2011-2022 走看看