CF1228E Another Filling the Grid

Description

题目链接

把 \(k\) 个数填进 \(n\times n\) 的网格中,要求每行每列的最小值均为 \(1\) ,求合法方案数对 \(10^9+7\) 取模的结果

\(1\le n\le 250,1\le k\le 10^9\)

Solution

看着标签是 \(\text{combinatorics}\) 和 \(\text{dp}\) 就看了看题目......

考虑从左向右 \(\text{dp}\) ,每列至少有一个 \(1\) ,同时考虑行的情况。对于某一列如果填完了 \(1\) ,那剩下的位置直接随便填非 \(1\) 的数就行了,设 \(dp_{i,j}\) 表示到了第 \(i\) 列,还有 \(j\) 行没有填 \(1\) 的方案数,方程就是
\[
dp_{i,j}=dp_{i-1,j}(k-1)^j(k^{n-j}-(k-1)^{n-j})+\sum\limits_{p=1}^{n-j}\dbinom{j+p}{p}dp_{i-1,j+p}k^{n-j-p}(k-1)^j
\]
其中 \(k^{n-j}-(k-1)^{n-j}\) 是为了保证这一列至少有一个 \(1\)

复杂度 \(O(n^3)\)

代码如下:

#include<cstdio>
#include<iostream>
using namespace std;
const int N=3e2+10;
const int mod=1e9+7;
int n,k,dp[N][N],c[N][N],bin[N],bin2[N];
inline void Add(int &x,int y){x+=y;x-=x>=mod? mod:0;}
inline int Minus(int x){x+=x<0? mod:0;return x;}
inline int MOD(int x){x-=x>=mod? mod:0;return x;}
inline void Preprocess(){
    for(register int i=0;i<=n;i++){
        c[i][0]=1;
        for(register int j=1;j<=i;j++)
            c[i][j]=MOD(c[i-1][j]+c[i-1][j-1]);
    }
    bin[0]=1;for(register int i=1;i<=n;i++)bin[i]=1ll*bin[i-1]*k%mod;
    bin2[0]=1;for(register int i=1;i<=n;i++)bin2[i]=1ll*bin2[i-1]*(k-1)%mod;
}
int main(){
    scanf("%d%d",&n,&k);Preprocess();dp[0][n]=1;
    for(register int i=1;i<=n;i++)
        for(register int j=0;j<=n;j++){
            Add(dp[i][j],1ll*dp[i-1][j]*bin2[j]%mod*(Minus(bin[n-j]-bin2[n-j]))%mod);
            for(register int p=1;p<=n-j;p++)
                Add(dp[i][j],1ll*c[j+p][p]*dp[i-1][j+p]%mod*bin[n-j-p]%mod*bin2[j]%mod);
        }
    printf("%d\n",dp[n][0]);
    return 0;
}

原文地址:https://www.cnblogs.com/ForwardFuture/p/11610829.html

时间: 2024-08-30 17:53:45

CF1228E Another Filling the Grid的相关文章

[Codeforces 1228E]Another Filling the Grid (排列组合+容斥原理)

[Codeforces 1228E]Another Filling the Grid (排列组合+容斥原理) 题面 一个\(n \times n\)的格子,每个格子里可以填\([1,k]\)内的整数.要保证每行每列的格子上的数最小值为1,有多少种方案 \(n \leq 250,k \leq 10^9\) 分析 这题有\(O(n^3)\)的dp做法,但个人感觉不如\(O(n^2 \log n)\)直接用数学方法求更好理解. 考虑容斥原理,枚举有\(i\)行最小值>1,有\(j\)行最小值>1,那

Another Filling the Grid

E. Another Filling the Grid 参考:Codeforces Round #589 (Div. 2)-E. Another Filling the Grid-容斥定理 容斥这个东西可以理解,但是运用到实际的时候,还是觉得有点迷迷糊糊的,不知道套公式会不会是一种可行的办法. 是时候也得把以前的知识温习一下了.... 具体的思路看参考的博客就可以理解了. 代码: // Created by CAD on 2019/10/2. #include <bits/stdc++.h>

Codeforces Round #589 (Div. 2) B——B. Filling the Grid

Suppose there is a h×wh×w grid consisting of empty or full cells. Let's make some definitions: riri is the number of consecutive full cells connected to the left side in the ii-th row (1≤i≤h1≤i≤h). In particular, ri=0ri=0 if the leftmost cell of the 

Codeforces 1228E. Another Filling the Grid

传送门 看到 $n=250$ 显然考虑 $n^3$ 的 $dp$ 设 $f[i][j]$ 表示填完前 $i$ 行,目前有 $j$ 列的最小值是 $1$ 的合法方案数 那么对于 $f[i][j]$ ,枚举 $f[i-1][k]$ ,有 $f[i][j]=\sum_{k=0}^{j}\binom{n-k}{j-k}f[i-1][k](m-1)^{n-j}m^k$ 这里 $m$ 就是题目的 $k$ $\binom{n-k}{j-k}$ 是因为多出来的 $j-k$ 列 $1$ 可以任选 $(m-1)^{

Codeforces Round #589 (Div. 2) Another Filling the Grid (dp)

题意:问有多少种组合方法让每一行每一列最小值都是1 思路:我们可以以行为转移的状态 附加一维限制还有多少列最小值大于1 这样我们就可以不重不漏的按照状态转移 但是复杂度确实不大行(减了两个常数卡过去的...) #include <bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; const double eps = 1e-6; const int N = 3e5+7; typedef long long ll; co

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++) #defi

B. Filling the Grid codeforces

题目链接:https://codeforces.com/contest/1228/problem/B #include <cstdio> #include <algorithm> #include <iostream> #include <vector> #include <cstring> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; string a[1005]; co

ffmpeg最全的命令参数

Hyper fast Audio and Video encoderusage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}... Getting help: -h -- print basic options -h long -- print more options -h full -- print all options (including all format and code

查看FFMPEG的全部帮助内容

ffmpeg -h full Hyper fast Audio and Video encoder usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}... Getting help: -h -- print basic options -h long -- print more options -h full -- print all options (including all