首页 > 代码库 > 【BZOJ】3139: [Hnoi2013]比赛

【BZOJ】3139: [Hnoi2013]比赛

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3139


 

  可以发现,答案之和得分的序列有关,而且和序列中每个元素的顺序无关。考虑HASH所有的状态,记忆化搜索即可。

  (取模出问题+没有判断是否访问,即答案为0的状态有的可能已经访问过了)调了一个多小时。


 

#include<iostream>#include<cstdio>#include<algorithm>#include<vector>#include<cstdlib>#include<cmath>#include<cstring>#include<map>using namespace std;#define maxn 12#define llg long long #define md 1000000007#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);llg n,m;map<llg,llg>f;bool cmp(llg a,llg b){return a<b;}struct node{    llg a[maxn],len;    void px() {sort(a+1,a+len+1,cmp);}    llg hash()    {        llg tot=len,x=1;        for (llg i=1;i<=len;i++)        {            tot*=28;            tot+=x*a[i];        }        //cout<<tot<<endl;        return tot;    }};llg ss(node w,llg x,llg res,llg up);llg dfs(node e);llg ss(node w,llg x,llg res,llg up){    llg ans=0;    if (x>up)    {        if (res==0) ans=dfs(w);        return ans;    }    if (res>=3)    {        ans+=ss(w,x+1,res-3,up); ans%=md;    }    if (res>=1 && w.a[x]>=1)    {        w.a[x]--;        ans+=ss(w,x+1,res-1,up);        ans%=md;        w.a[x]++;    }    if (w.a[x]>=3)    {        w.a[x]-=3;        ans+=ss(w,x+1,res,up);        ans%=md;        w.a[x]+=3;    }    return ans%md;}llg dfs(node e){    e.px();    llg val=e.hash();    if (f[val]!=0) return max((llg)0,f[e.hash()]);    node ne=e;    for (llg i=1;i<e.len;i++) ne.a[i]=ne.a[i+1];    ne.len=e.len-1; ne.a[e.len]=0;    f[val]=ss(ne,1,e.a[1],e.len-1)%md;    if (f[val]==0) f[val]=-1;//    cout<<e.hash()<<endl;    return max((llg)0,f[val]);}int main(){    yyj("match");    cin>>n;    node w; w.len=n;    memset(w.a,0,sizeof(w.a));    for (llg i=1;i<=n;i++) scanf("%lld",&w.a[i]);    w.px(); f[0]=1;    dfs(w);    cout<<max((llg)0,f[w.hash()]);    return 0;}

 

【BZOJ】3139: [Hnoi2013]比赛