• codeforces 814E An unavoidable detour for home


    题目链接

    正解:$dp$。

    感觉这道题就是中国象棋的加强版。。我们要发现一些性质。

    首先就是这个图肯定是一个按照$bfs$序分层的图,且每个点只往自己上面那一层连了一条边,每个点不可能向自己的上面超过两层的点连边。

    又因为$l_{i}leq l_{i+1}$,所以实际上$bfs$序相同的点是连续的。

    然后我们就可以$dp$了,设$f[i][a][b][c][d]$表示处理了前i个点,上一层还有a个点度数为1,b个点度数为2,这一层还有c个点度数为1,d个点度数为2。

    然后我们直接转移就行了,转移就是对于当前点,枚举它的连边情况,它肯定会往上一层连一条边,同时也可能往自己这一层连边,剩下的边就留给下一层就行了。

    最终答案就是$f[n][0][0][0][0]$。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define rhl (1000000007)
     6 
     7 using namespace std;
     8 
     9 int f[2][51][51][51][51],du[51],n;
    10 //f[i][a][b][c][d]表示处理了前i个点,上一层还有a个点度数为1,b个点度数为2,这一层还有c个点度数为1,d个点度数为2
    11 
    12 il int gi(){
    13   RG int x=0,q=1; RG char ch=getchar();
    14   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    15   if (ch=='-') q=-1,ch=getchar();
    16   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    17   return q*x;
    18 }
    19 
    20 il void add(RG int &x,RG int v){
    21   x+=v; if (x>=rhl) x-=rhl; return;
    22 }
    23 
    24 int main(){
    25 #ifndef ONLINE_JUDGE
    26   freopen("home.in","r",stdin);
    27   freopen("home.out","w",stdout);
    28 #endif
    29   n=gi();
    30   for (RG int i=1;i<=n;++i) du[i]=gi();
    31   f[0][du[1]==2][du[1]==3][du[2]==2][du[2]==3]=1;
    32   for (RG int i=2,pre=1,cur=0;i<n;++i,pre=cur,cur^=1){
    33     memset(f[pre],0,sizeof(f[pre]));
    34     for (RG int a=0;a<=i;++a)
    35       for (RG int b=0;a+b<=i;++b)
    36     for (RG int c=0;a+b+c<=i;++c)
    37       for (RG int d=0,res;a+b+c+d<=i;++d){
    38         res=f[cur][a][b][c][d]; if (!res) continue;
    39         if (!a && !b){
    40           if (c || d) add(f[cur][c][d][0][0],res); continue;
    41         }
    42         if (du[i+1]==2){
    43           if (a){
    44         add(f[pre][a-1][b][c+1][d],1LL*res*a%rhl);
    45         if (c) add(f[pre][a-1][b][c-1][d],1LL*res*a*c%rhl);
    46         if (d) add(f[pre][a-1][b][c+1][d-1],1LL*res*a*d%rhl);
    47           }
    48           if (b){
    49         add(f[pre][a+1][b-1][c+1][d],1LL*res*b%rhl);
    50         if (c) add(f[pre][a+1][b-1][c-1][d],1LL*res*b*c%rhl);
    51         if (d) add(f[pre][a+1][b-1][c+1][d-1],1LL*res*b*d%rhl);
    52           }
    53         } else{
    54           if (a){
    55         add(f[pre][a-1][b][c][d+1],1LL*res*a%rhl);
    56         if (c) add(f[pre][a-1][b][c][d],1LL*res*a*c%rhl);
    57         if (d) add(f[pre][a-1][b][c+2][d-1],1LL*res*a*d%rhl);
    58         if (c && d) add(f[pre][a-1][b][c][d-1],1LL*res*a*c*d%rhl);
    59         if (c>=2) add(f[pre][a-1][b][c-2][d],1LL*res*(a*c*(c-1)>>1)%rhl);
    60         if (d>=2) add(f[pre][a-1][b][c+2][d-2],1LL*res*(a*d*(d-1)>>1)%rhl);
    61           }
    62           if (b){
    63         add(f[pre][a+1][b-1][c][d+1],1LL*res*b%rhl);
    64         if (c) add(f[pre][a+1][b-1][c][d],1LL*res*b*c%rhl);
    65         if (d) add(f[pre][a+1][b-1][c+2][d-1],1LL*res*b*d%rhl);
    66         if (c && d) add(f[pre][a+1][b-1][c][d-1],1LL*res*b*c*d%rhl);
    67         if (c>=2) add(f[pre][a+1][b-1][c-2][d],1LL*res*(b*c*(c-1)>>1)%rhl);
    68         if (d>=2) add(f[pre][a+1][b-1][c+2][d-2],1LL*res*(b*d*(d-1)>>1)%rhl);
    69           }
    70         }
    71       }
    72   }
    73   cout<<f[n&1][0][0][0][0]; return 0;
    74 }
  • 相关阅读:
    dedeCMS自定义dede标签
    phpstrom配置Xdebug
    ElasticSearch安装 --- windows版
    MySQL语句优化
    PHP高并发商城秒杀
    【java_需阅读】Java中static关键字用法总结
    【java】public,private和protected
    PICT测试工具的安装及使用
    【android】Android am命令使用
    【python】获取指定网页上的所有超级链接
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7809657.html
Copyright © 2020-2023  润新知