zoukankan      html  css  js  c++  java
  • [Luogu5241]序列(DP)

    固定一种构造方法,使它能够构造出所有可能的序列。

    对于一个要构造的序列,把所有点排成一串,若a[i]=a[i-1],那么从1所在弱连通块往连通块后一个点连,若所有点都在一个连通块里了,就在1所在强连通块中随便连。若a[i]<a[i-1],那么连一条从后往前的边让若干点与1所在强连通快合并。显然这样可以得到所有可能的序列。

    于是前一部分“连弱连通块”用f[i][k][x]表示前i个点在一个弱连通块中,到目前为止序列共减小了k次,1所在连通块大小为x,的方案数(此时边数为i-1+k)。

    后一部分用g[i][x]表示图中共i条边,1所在连通块大小为x的方案数。

    两个状态数都是$O(n^3)$的且可以用前缀和$O(1)$转移,g[][]的初值由f[][][]得到。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     4 using namespace std;
     5 
     6 const int N=410,mod=1e9+7;
     7 int n,f[N][N][N],g[N*N][N],smf[N][N][N],smg[N*N][N],res[N*N];
     8 
     9 int inc(int x,int y){ x+=y; return x>=mod ? x-mod : x; }
    10 
    11 int main(){
    12     freopen("c.in","r",stdin);
    13     freopen("c.out","w",stdout);
    14     scanf("%d",&n); f[1][0][1]=smf[1][0][1]=1;
    15     rep(i,2,n) rep(k,0,i-1) rep(x,1,i){
    16         f[i][k][x]=f[i-1][k][x];
    17         if (k && i<n) f[i][k][x]=inc(f[i-1][k][x],smf[i][k-1][x-1]);
    18         smf[i][k][x]=inc(smf[i][k][x-1],f[i][k][x]);
    19         if (i<n) res[i-1+k]=inc(res[i-1+k],f[i][k][x]);
    20         if (i==n) g[i-1+k][x]=inc(g[i-1+k][x],f[i][k][x]);
    21     }
    22     rep(i,1,n*(n-1)) rep(x,1,n) if (i<=n*(n-1)/2+x*(x-1)/2){
    23         g[i][x]=inc(inc(g[i][x],g[i-1][x]),smg[i-1][x-1]);
    24         smg[i][x]=inc(smg[i][x-1],g[i][x]);
    25     }
    26     rep(i,1,n*(n-1)){
    27         int ans=0;
    28         rep(x,1,n) ans=inc(ans,g[i][x]);
    29         printf("%d ",inc(ans,res[i]));
    30     }
    31     return 0;
    32 }
  • 相关阅读:
    Uva455
    PAT乙级1059
    PAT乙级1092
    PAT乙级1076
    PAT乙级1065
    PAT乙级1049
    Uva1586
    《肇造区夏》读后感 读书笔记
    《老鼠虱子和历史》读后感 读书笔记
    《胡适口述自传》读后感 读书笔记
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10476442.html
Copyright © 2011-2022 走看看