【BZOJ】3139: [Hnoi2013]比赛

时间:2023-12-30 17:04:32

题目链接: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+,a+len+,cmp);}
llg hash()
{
llg tot=len,x=;
for (llg i=;i<=len;i++)
{
tot*=;
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=;
if (x>up)
{
if (res==) ans=dfs(w);
return ans;
}
if (res>=)
{
ans+=ss(w,x+,res-,up); ans%=md;
}
if (res>= && w.a[x]>=)
{
w.a[x]--;
ans+=ss(w,x+,res-,up);
ans%=md;
w.a[x]++;
}
if (w.a[x]>=)
{
w.a[x]-=;
ans+=ss(w,x+,res,up);
ans%=md;
w.a[x]+=;
}
return ans%md;
} llg dfs(node e)
{
e.px();
llg val=e.hash();
if (f[val]!=) return max((llg),f[e.hash()]);
node ne=e;
for (llg i=;i<e.len;i++) ne.a[i]=ne.a[i+];
ne.len=e.len-; ne.a[e.len]=;
f[val]=ss(ne,,e.a[],e.len-)%md;
if (f[val]==) f[val]=-;
// cout<<e.hash()<<endl;
return max((llg),f[val]);
} int main()
{
yyj("match");
cin>>n;
node w; w.len=n;
memset(w.a,,sizeof(w.a));
for (llg i=;i<=n;i++) scanf("%lld",&w.a[i]);
w.px(); f[]=;
dfs(w);
cout<<max((llg),f[w.hash()]);
return ;
}