码迷,mamicode.com
首页 > 其他好文 > 详细

51nod 1231 记分牌

时间:2017-05-04 12:05:51      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:gis   opened   etc   hid   mod   htm   target   大于   std   

链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1231

一个得分合法等价于前k小的得分之和大于等于$\frac{k*(k-1)}{2}$

听说是竞赛图的经典结论,可是我不会证。

技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#define w(x) (x)*(x-1)/2
using namespace std;

int read_p,read_ca,read_f;
inline int read(){
    read_p=0;read_ca=getchar();read_f=1;
    while(read_ca<0||read_ca>9) {if (read_ca==-) read_f=-1;read_ca=getchar();}
    while(read_ca>=0&&read_ca<=9) read_p=read_p*10+read_ca-48,read_ca=getchar();
    return read_p*read_f;
}
const int MOD=1e9+7;
int T,n,m,mmh[42][42][1611],a,t[42],q[42],C[42][42];
inline void M(int &x){while(x>=MOD)x-=MOD;}
int main(){
    register int i,j,k,l;
    T=read();
    C[0][0]=1;
    for (i=1;i<=40;i++)
    for (C[i][0]=1,j=1;j<=i;j++) M(C[i][j]=C[i-1][j]+C[i-1][j-1]);
    while (T--){
        n=read();
        memset(mmh,0,sizeof(mmh));memset(t,0,sizeof(t));
        for (i=0;i<n;i++){
            a=read();
            if (a!=-1) t[a]++;else t[n]++;
        }
        if (t[0]>1) {puts("0");continue;}
        if (t[0]==0) if (mmh[0][0][0]=1,t[n]) mmh[1][0][0]=C[t[n]][1];
        if (t[0]==1) mmh[1][0][0]=1;q[0]=t[0];
        for (i=1;i<n;i++) q[i]=q[i-1]+t[i];
        for (i=0;i<=n;i++)
        for (j=1;j<n;j++)
        for (k=0;k<=n*n;k++)
        if (mmh[i][j-1][k]){
            for (l=0;l<=t[j];l++) if (k+j*l<w(i+l)) break;
            if (l<=t[j]) continue;
            for (l=t[j];l<=q[j]+t[n]-i;l++)
            if (k+j*l>=w(i+l)) M(mmh[i+l][j][k+j*l]+=1LL*mmh[i][j-1][k]*C[t[n]-(i-q[j-1])][l-t[j]]%MOD);
        }
        printf("%d\n",mmh[n][n-1][w(n)]);
    }
}
View Code

 

51nod 1231 记分牌

标签:gis   opened   etc   hid   mod   htm   target   大于   std   

原文地址:http://www.cnblogs.com/Enceladus/p/6806181.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!