bzoj千题计划294:bzoj3139: [Hnoi2013]比赛

Posted 日拱一卒 功不唐捐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj千题计划294:bzoj3139: [Hnoi2013]比赛相关的知识,希望对你有一定的参考价值。

http://www.lydsy.com/JudgeOnline/problem.php?id=3139

 

队伍的顺序不会影响结果

将队伍的得分情况作为状态,记忆化搜索

 

就是先搜索第一只队伍的得分情况,即为他分配分数

当第一只队伍的分数分配完时,它与其他队伍的比拼会使其他队伍也分配到了一定的分数

将其他队伍分配到的分数 这个状态 哈希

然后第二支队……,这就是子问题

 

啊啊啊,我也不知道我在说啥了

 

myl考场AC tql!!!

 

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>

#define N 11

using namespace std;

typedef long long LL;

const int mod=1e9+7;

int n,w[N];

map<LL,int>mp[N];

LL gethash(int *b,int p)
{
    LL S=0;
    for(int i=p;i<=n;++i) S=S*28+b[i];
    return S;
}

int dfs(int *val,int l,int r)
{
    if(l==r)
    {
        if(val[l]) return 0;
        if(l==n) return 1;
        int b[N];
        memcpy(b,val,sizeof(b));
        sort(b+l+1,b+n+1);
        LL S=gethash(b,l+1);
        if(mp[l+1].find(S)==mp[l+1].end()) mp[l+1][S]=dfs(b,l+1,n);
        return mp[l+1][S];
    }
    if(3*(r-l)<val[l]) return 0;
    int tot=0;
    if(val[l]>=3)
    {
        val[l]-=3;
        tot+=dfs(val,l,r-1);
        tot-=tot>=mod ? mod : 0;
        val[l]+=3;
    }
    if(val[l] && val[r])
    {
        val[l]--; val[r]--;
        tot+=dfs(val,l,r-1);
        tot-=tot>=mod ? mod : 0;
        val[l]++; val[r]++;
    }
    if(val[r]>=3)
    {
        val[r]-=3;
        tot+=dfs(val,l,r-1);
        tot-=tot>=mod ? mod : 0;
        val[r]+=3;
    }
    return tot;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&w[i]);
    printf("%d",dfs(w,1,n));
}

 

以上是关于bzoj千题计划294:bzoj3139: [Hnoi2013]比赛的主要内容,如果未能解决你的问题,请参考以下文章

bzoj千题计划197:bzoj4247: 挂饰

bzoj千题计划118:bzoj1028: [JSOI2007]麻将

bzoj千题计划165:bzoj5127: 数据校验

bzoj千题计划144:bzoj1176: [Balkan2007]Mokia

bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

bzoj千题计划142:bzoj3144: [Hnoi2013]切糕