zoukankan      html  css  js  c++  java
  • HDU5779 Tower Defence (BestCoder Round #85 D) 计数dp

    分析(官方题解):

    一点感想:(这个题是看题解并不是特别会转移,当然写完之后看起来题解说得很清晰,主要是人太弱

                    这个题是参考faebdc神的代码写的,说句题外话,很荣幸高中和faebdc巨一个省,虽然本弱渣高中都没搞过oi)

                  最短路不等于k,所以根本不存在最短路>=k的,因为存在的话,由最短路知识可知,k+1一定是由k更新过来的,矛盾

                  所以最短路不等于k,即最短路小于k

                  然后就是不管是多校还是bc,都能碰到有关图的计数类的dp问题,比如2016多校1的刚性图,计算连通二分图的数量

                  这个题是计算无向图,满足最短路小于k的数量

                  这类题对于我来说比较难,看了题解以后可能还好一点,关键是定义状态

                  这个题定义的状态是f[i][j][k]很巧妙,在统计的时候可以保证不重不漏,在更新的时候,正好可以像求解最短路一样按距离一层一层更新

                  只能说还是太年轻,不能定义出这么好的状态,既方便统计,又方便转移,总得来说还是要努力提高姿势

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef  long long LL;
    const int N = 65;
    const LL mod = 1e9+7;
    int T,n,m;
    inline LL up(LL x,LL y){
      x+=y;if(x>=mod)x-=mod;
      return x;
    }
    LL f[N][N][N],pw2[N*N/2],pw2_1[N],c[N][N];
    void init(){
      for(int i=0;i<=60;++i){
        c[i][0]=c[i][i]=1;
        for(int j=1;j<i;++j){
          c[i][j]=up(c[i-1][j-1],c[i-1][j]); 
        }
      }
      pw2_1[0]=pw2[0]=1;
      for(int i=1;i<=1800;++i)
        pw2[i]=pw2[i-1]*2%mod; 
      for(int i=1;i<=60;++i)
        pw2_1[i]=pw2_1[i-1]*2%mod;
      for(int i=0;i<=60;++i)
        pw2_1[i]=up(pw2_1[i],mod-1);
      f[1][0][1]=1;
      for(int i=1;i<=60;++i)
       for(int j=0;j<i;++j)
        for(int k=1;k<=i;++k){
         if(!f[i][j][k])continue;
         LL tmp=f[i][j][k];
         for(int s=1;s+i<=60;++s){
           tmp=tmp*pw2_1[k]%mod;LL val=tmp;
           val=val*pw2[s*(s-1)/2]%mod;
           val=val*c[s+i-1][s]%mod;
           f[s+i][j+1][s]=up(f[s+i][j+1][s],val);
          }
        }
    }
    void work(){
       scanf("%d%d",&n,&m);LL ret=0;
       for(int i=1;i<=n;++i)
        for(int j=0;j<m;++j)
         for(int k=1;k<=i;++k){
          if(!f[i][j][k])continue;
           LL tmp=f[i][j][k];
           tmp=tmp*c[n-1][n-i]%mod;
           tmp=tmp*pw2[(n-i)*(n-i-1)/2]%mod;
           ret=up(ret,tmp);
         }
      printf("%I64d
    ",ret);
    }
    int main(){ 
      init();
      scanf("%d",&T);
      for(int i=0;i<T;++i)work();
      return 0;
    }
    View Code
  • 相关阅读:
    树莓派搭建NAS之Seaflile
    Samba配置不同用户组不同用户的访问权限
    Samba-Linux权限理解
    Samba 共享配置
    服务端主动给客户端推送消息
    drf 权限认证
    drf-jwt分页器详解
    drf-jwt的过滤,筛选,排序,分页组件
    jwt token认证
    jwt
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5722950.html
Copyright © 2011-2022 走看看