P3154 [CQOI2009]循环赛

Posted bztminamoto

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3154 [CQOI2009]循环赛相关的知识,希望对你有一定的参考价值。

传送门

双倍经验题->这里

//minamoto
#include<bits/stdc++.h>
#define ll unsigned long long
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
using namespace std;
const ll Base=17,P=1e9+7;const int N=1005;
int n,m,a[N],b[N],s[N],su,sx,sy;map<ll,ll>h;
inline bool cmp(const R int &x,const R int &y){return x>y;}
ll dfs(int u,int v){
    ll res=0;if(u==n)return 1;if(a[u]+3*(n-v+1)<s[u])return 0;
    if(v>n){
        fp(i,u+1,n)b[i]=s[i]-a[i];sort(b+u+1,b+n+1);
        ll S=0;fp(i,u+1,n)S=S*Base+b[i];
        if(h.count(S))return h[S];
        return h[S]=dfs(u+1,u+2);
    }
    if(a[u]+3<=s[u]&&sx)a[u]+=3,--sx,res+=dfs(u,v+1),a[u]-=3,++sx;
    if(a[u]+1<=s[u]&&a[v]+1<=s[v]&&sy)++a[u],++a[v],--sy,res+=dfs(u,v+1),--a[u],--a[v],++sy;
    if(a[v]+3<=s[v]&&sx)a[v]+=3,--sx,res+=dfs(u,v+1),++sx,a[v]-=3;
    return res%P;
}
int main(){
//  freopen("testdata.in","r",stdin);
    scanf("%d",&n);fp(i,1,n)scanf("%d",&s[i]),su+=s[i];
    sx=su-n*n+n,sy=(su-3*sx)>>1;sort(s+1,s+1+n,cmp);
    printf("%lld
",dfs(1,2)%P);return 0;
}

以上是关于P3154 [CQOI2009]循环赛的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1306: [CQOI2009]match循环赛(模拟爆搜)

BZOJ 1303 CQOI2009中位数图

bzoj1303: [CQOI2009]中位数图

AC日记——[CQOI2009]DANCE跳舞 洛谷 P3153

p1627 [CQOI2009]中位数

bzoj 1305: [CQOI2009]dance跳舞