zoukankan      html  css  js  c++  java
  • E. Another Filling the Grid 状压dp

      http://codeforces.com/contest/1228/my

     题意:有个nm的矩形  每个格子可以取1-k中的一种数字  问有多少种填法  使得每行每列至少都有一个1

    题解:设置dp[i][j] 表示 当前处理到i行有j列为1的方案数   然后统计答案贡献即可   注意改行至少取一个1

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=300;
    const ll mod=1e9+7;
    ll dp[N][N],mi[N],mi_1[N],C[N][N],n,k;
    int main()
    {
        cin>>n>>k;
        rep(i,0,n)
        {
            C[i][0]=1;
            rep(j,1,i)C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
        }
        mi[0]=mi_1[0]=1;
        rep(i,1,n)mi[i]=mi[i-1]*k%mod,mi_1[i]=mi_1[i-1]*(k-1)%mod;
        rep(i,1,n)dp[1][i]=C[n][i]*mi_1[n-i]%mod;
        rep(i,2,n)rep(j,0,n)rep(s,0,j)
        { 
          dp[i][j]=(dp[i][j]+dp[i-1][s]*C[n-s][j-s]%mod*mi[s]%mod*mi_1[n-j]%mod)%mod;
          if(j==s)dp[i][j]=(dp[i][j]-mi_1[n]*dp[i-1][s]%mod+mod)%mod;//一定要容斥掉全部非一的方案数
        }
        cout<<dp[n][n];
        return 0;
    }
    View Code
  • 相关阅读:
    是否是轮回(续)
    夜雨做成秋
    53分
    浮生六记 一成长星和月
    企业信息化常见缩略语汇总
    是否是轮回
    对信号集操作函数的使用方法和顺序
    fcntl.h
    关于linux信号量的基本使用
    linux 共享内存
  • 原文地址:https://www.cnblogs.com/bxd123/p/11618291.html
Copyright © 2011-2022 走看看