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

CF848D Shake It!

时间:2020-02-02 15:27:45      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:str   sum   +=   背包   int   string   优秀   tps   its   

Link
我们考虑dp,设\(f_{i,j}\)表示进行\(i\)次操作后Mincut为\(j\)的方案数。
转移与背包类似,考虑枚举成对的\(f\)进行转移,对于\(f_{i,j}\),我们枚举\(f_{a,b},f_{c,d}\),使得\(f_{i,j}\)\(s\)\(f_{a,b}\)\(s\)重合,\(f_{a,b}\)\(t\)\(f_{c,d}\)\(s\)重合,\(f_{c,d}\)\(t\)\(f_{i,j}\)\(t\)重合,然后再枚举添加\(x\)\(f_{a,b}-f_{c,d}\)
这样就有:\(f_{i,j}{f_{a,b}f_{c,d}+x-1\choose x}\rightarrow f_{i+x(a+c+1),j+x\min(b,d)}\)
这样做的时间复杂度是\(O(n^6\log n)\)(枚举\(x\)的复杂度为调和级数),无法接受。
考虑优化,设\(g_{i,j}=\sum\limits[a+c+1=i\wedge\min(b,d)=j]f_{a,b}f_{c,d}\),这样我们就可以先求出\(g_{i,j}\)再更新\(f_{i,j}\),时间复杂度为\(O(n^4\log n)\),非常优秀。

#include<cstdio>
#include<cstring>
const int N=57,P=1000000007;
void mod(int&x){x-=P,x+=x>>31&P;}
int mul(int a,int b){return 1ll*a*b%P;}
int f[N][N],g[N][N],t[N][N],inv[N];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m),inv[0]=inv[1]=f[0][1]=1;
    for(int i=2;i<=n;++i) inv[i]=mul(inv[P%i],P-P/i);
    for(int i=1;i<=n;++i)
    for(int j=1;j<=i+1;++j)
    {
        for(int k=0;k<=i-1;++k)
        {
        for(int l=j;l<=k+1;++l) mod(g[i][j]+=mul(f[k][l],f[i-1-k][j]));
        for(int l=j+1;l<=i-k;++l) mod(g[i][j]+=mul(f[k][j],f[i-1-k][l]));
        }
        memset(t,0,sizeof t);
        for(int k=0;k<=n;++k) for(int p=1;p<=k+1;++p) for(int q=1,s=1;k+q*i<=n;++q) s=mul(mul(s,g[i][j]+q-1),inv[q]),mod(t[k+q*i][p+q*j]+=mul(f[k][p],s));
        for(int k=0;k<=n;++k) for(int l=1;l<=k+1;++l) mod(f[k][l]+=t[k][l]);
    }
    printf("%d",f[n][m]);
}

CF848D Shake It!

标签:str   sum   +=   背包   int   string   优秀   tps   its   

原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12252235.html

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