zoukankan      html  css  js  c++  java
  • [HEOI2013]SAO

    题目描述

    Welcome to SAO ( Strange and Abnormal Online)。这是一个 VR MMORPG, 含有 n 个关卡。但是,挑战不同关卡的顺序是一个很大的问题。

    有 n – 1 个对于挑战关卡的限制,诸如第 i 个关卡必须在第 j 个关卡前挑战, 或者完成了第 k 个关卡才能挑战第 l 个关卡。并且,如果不考虑限制的方向性, 那么在这 n – 1 个限制的情况下,任何两个关卡都存在某种程度的关联性。即, 我们不能把所有关卡分成两个非空且不相交的子集,使得这两个子集之间没有任 何限制。

    输入格式

    第一行,一个整数 T,表示数据组数。

    对于每组数据,第一行一个整数 n,表示关卡数。接下来 n – 1 行,每行为 “i sign j”,其中 0 ≤ i, j ≤ n – 1 且 i ≠ j,sign 为“<”或者“>”,表示第 i 个关卡 必须在第 j 个关卡前/后完成。

    输出格式

    对于每个数据,输出一行一个整数,为攻克关卡的顺序方案个数,mod 1,000,000,007 输出。

    输入输出样例

    输入 #1
    2 
    5 
    0 < 2 
    1 < 2 
    2 < 3 
    2 < 4 
    4 
    0 < 1 
    0 < 2 
    0 < 3
    输出 #1
    4 
    6

    说明/提示

    对于 20%的数据有 n ≤ 10。

    对于 40%的数据有 n ≤ 100。

    对于另外 20%的数据有,保证数据中 sign 只会是<,并且 i < j。

    对于 100%的数据有 T ≤ 5,1 ≤ n ≤ 1000。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 struct Node
     8 {
     9     int next,to,w;
    10 }edge[2001];
    11 int head[1001],num,vis[1001],n;
    12 ll size[1005],f[1005][1005],Mod=1e9+7,C[1005][1005],F[1005];
    13 void add(int x,int y,int w)
    14 {
    15     num++;
    16     edge[num].next=head[x];
    17     edge[num].to=y;
    18     head[x]=num;
    19     edge[num].w=w;
    20 }
    21 void dfs(int x)
    22 {int i,p1,p3;
    23     size[x]=1;f[x][1]=1;
    24     vis[x]=1;
    25     for (i=head[x];i;i=edge[i].next)
    26     {
    27         int v=edge[i].to;
    28         if (vis[v]) continue;
    29         dfs(v);
    30         memcpy(F,f[x],sizeof(F));
    31         memset(f[x],0,sizeof(f[x]));
    32         if (edge[i].w==1)
    33         {
    34             for (p1=1;p1<=size[x];p1++)
    35             for (p3=p1;p3<=p1+size[v]-1;p3++)
    36             (f[x][p3]+=C[p3-1][p1-1]*C[size[x]+size[v]-p3][size[x]-p1]%Mod*F[p1]%Mod*(f[v][size[v]]-f[v][p3-p1]+Mod)%Mod)%=Mod;
    37         }
    38         else 
    39         {
    40             for (p1=1;p1<=size[x];p1++)
    41             for (p3=p1+1;p3<=p1+size[v];p3++)
    42             (f[x][p3]+=C[p3-1][p1-1]*C[size[x]+size[v]-p3][size[x]-p1]%Mod*F[p1]%Mod*f[v][p3-p1]%Mod)%=Mod;    
    43         }
    44         size[x]+=size[v];
    45     }
    46     for (i=1;i<=size[x];i++)
    47     (f[x][i]+=f[x][i-1])%=Mod;
    48 }
    49 int main()
    50 {int T,i,x,y,j;
    51 char ch;
    52     scanf("%d",&T);
    53     C[0][0]=1;
    54     for (i=1;i<=1000;i++)
    55     {
    56         C[i][0]=1;
    57         for (j=1;j<=i;j++)
    58          C[i][j]=(C[i-1][j-1]+C[i-1][j])%Mod;
    59     }
    60     while (T--)
    61     {
    62         scanf("%d",&n);
    63         memset(head,0,sizeof(head));
    64         memset(edge,0,sizeof(edge));
    65         memset(f,0,sizeof(f));
    66         memset(vis,0,sizeof(vis));
    67         num=0;
    68         for (i=1;i<n;i++)
    69         {
    70             scanf("%d %c %d",&x,&ch,&y);
    71             x++;y++;
    72             add(x,y,ch=='<');
    73             add(y,x,ch=='>');
    74         }
    75         dfs(1);
    76         printf("%lld
    ",f[1][n]);
    77     }
    78 }
  • 相关阅读:
    四则运算结对作业
    读《构建之法》第四、十七章有感
    四则运算练习的命令行软件
    Spring01
    oop01
    运行shell脚本的三种方式
    正则表达式的基础组成部分
    C语言文件函数
    shell文件描述符及重定向
    shell基础
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/12254228.html
Copyright © 2011-2022 走看看