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)); }