• [HNOI2013]比赛 (用Hash实现记忆化搜索)


    [HNOI2013]比赛

    题目描述

    沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛。此次联 赛共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 
    

    但沫沫发现当球队较多时,计算工作量将非常大,所以这个任务就交给你了。请你计算 出可能的比赛过程的数目,由于答案可能很大,你只需要输出答案对10^9+7取模的结果

    输入格式:

    第一行是一个正整数N,表示一共有N支球队。 接下来一行N个非负整数,依次表示各队的最后总得分。 输入保证20%的数据满足N<=4,40%的数据满足N<=6,60%的数据满足N<=8,100%的数据 满足3<=N<=10且至少存在一组解。

    输出格式:

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

    输入样例#1:

    4
    4 3 6 4

    输出样例#1:

    3

    说明:

    20%的数据满足N≤4;

    40%的数据满足N≤6;

    60%的数据满足N≤8;

    100%的数据满足3≤N≤10且至少存在一组解。

    solution:

    因为数据范围小,且每一队分数不会大于27所以可以开个long long的map来进行记忆化。从第一队枚举,每枚举一对即可进行一次hash记忆化。注意一定要以每一队还需要的分数来hash不然会出错(性质不一样)(这样连样例都难过),还有hash之前排个序可以去重(快一些)(可以画图证明,枚举完一队后其他队所需分数可以互换)!

    但因为是long long 的map速度不够优秀,所以剪枝很关键(暴力搜索,剪枝优秀的话可以60分)!

    code:

    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<ctime>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    
    #define ll long long
    #define db double
    #define inf 0x7fffffff
    #define rg register int
    #define mod 1000000007
    
    using namespace std;
    
    int n,x,y,z;
    int a[11],b[11],s[11];
    
    map<ll,ll> h;
    
    inline int qr(){
        char ch;
        while((ch=getchar())<'0'||ch>'9');
        int res=ch^48;
        while((ch=getchar())>='0'&&ch<='9')
            res=res*10+(ch^48);
        return res;
    }
    
    inline ll dfs(int i,int j){ll res=0;
        if(a[i]-3*(n-j+1)>0)return 0;
        if(j>n){
            if(i==n-1)return 1;
            for(rg k=i+1;k<=n;++k)
                b[k]=a[k];
            sort(b+i+1,b+n+1);
            for(rg k=i+1;k<=n;++k)
                res=res*27+b[k]+1;
            if(h.find(res)!=h.end()){
                return h[res];
            }
            return h[res]=dfs(i+1,i+2);
        }
        if(a[i]>2&&x){
            a[i]-=3;--x;
            res+=dfs(i,j+1);
            a[i]+=3;++x;
        }
        if(a[j]>2&&x){
            a[j]-=3;--x;
            res+=dfs(i,j+1);
            a[j]+=3;++x;
        }
        if(a[i]&&a[j]&&y){
            --a[i];--a[j];--y;
            res+=dfs(i,j+1);
            ++a[i];++a[j];++y;
        }return res;
    }
    
    int main(){
        //freopen("match.in","r",stdin);
        //freopen("match.out","w",stdout);
        n=qr();
        for(rg i=1;i<=n;++i)
            z+=(s[i]=qr());
        sort(s+1,s+n+1);
        for(rg i=1;i<=n;++i)
            a[i]=s[i];
        x=z-n*n+n,y=(z-3*x)>>1;
        printf("%lld
    ",dfs(1,2)%mod);
        return 0;
    }
    
    ✐☎博主撰文不易,转载还请注明出处;若对本文有疑,请私信或在下方讨论中提出。O(∩_∩)O谢谢!☏

    ☃〔尽管小伙伴们肯定有千百种方式针对,但博主还是极其非常十分不要脸的把反对键吃掉辣!〕☃

    ✿『$At$ $last$:非常一(hu)本(shuo)正(ba)经(dao)的:博主很笨,请不要欺负他』✿✍

  • 相关阅读:
    Scrapy框架
    爬虫高性能相关
    存储库之MongoDB
    存储库之redis
    beautifulsoup
    pyecharts
    wxpy模块
    Gin框架
    Python的rabbitMQ
    Vue基础
  • 原文地址:https://www.cnblogs.com/812-xiao-wen/p/10306353.html
Copyright © 2020-2023  润新知