CS academy Binary Flips(dp)
开学啦,没啥时间写博客。。过几天就能又停课啦qwq
做点中等 \(dp\) 题来找找
noip的感觉 233
题意
给你一个 \(n \times m\) 的矩阵 \(A\) ,一开始全是 \(0\) 。
然后你可以对这个矩阵进行 \(k\) 次操作:
- 每次选择一个宫格 \((i, j)\) ,将第 \(i\) 行和第 \(j\) 列的状态翻转。(注意 \((i, j)\) 这个点的状态翻转两次然后不会改变)
问最后使得 \(A\) 中恰好有 \(S\) 个宫格被染黑的方案数。
\(1 \le n, m, k \le 3000\)
题解
思路很简单,首先我们考虑最后如果有 \(a\) 行被染了奇数次, \(b\) 列被染了奇数次,那么最后被染黑(变成 \(1\) )的格子数就是 \(a * m + b * n - 2 * a * b\) 。
我们可以暴力枚举 \(a, b\) 然后判断它得到面积是否为 \(S\) 。
然后我们就要考虑计算一个数,表示 \(k\) 次操作后,恰好有 \(a\) 行且 \(b\) 列被染黑的方案数。
我们很容易发现行和列的方案是互不影响的,然后我们可以考虑计算 \(k\) 次操作后,恰好有 \(a\) 行是染黑的方案数。
这个很显然可以用一个 \(dp\) 来计算,令 \(f_{i, j}\) 表示第 \(i\) 次操作后,恰好有 \(j\) 行染黑的方案数。
\]
这个转移意义十分的显然(就是忽略每行的区别,直接计算有几种方案使得它发生变化)
对与列的 \(dp\) 也是一样的。 然后就能很轻松的做完啦qwq
复杂度是 \(O(k(n + m) + nm)\) 的。
总结
忽略一些表面上的区别,把本质相同的当做一个状态去转移就行了。
后记
我总认为这个题可以把 \(n, m, k\) 出到 \(10^5\) 乃至 \(10^6\) 。
对于 \(a, b\) 的枚举,我们可以单枚举一个,然后快速算出另外一个。(因为是一次函数,所以一一对应)
然后瓶颈就在求那个每行的方案数上了。
那个应该可以用生成函数等高端计数技巧来进行优化,目前我还没有找出规律qwq
其实可以用线性代数魔法优化到 \(O(n \log n \log k)\) ,就是特征多项式用 \(NTT\) 转移即可。
代码
#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
typedef long long ll;
inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;}
inline int read() {
int x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
return x * fh;
}
const int N = 3e3 + 1e2, Mod = 1e9 + 7;
void File() {
#ifdef zjp_shadow
freopen ("binary-flips.in", "r", stdin);
freopen ("binary-flips.out", "w", stdout);
#endif
}
ll dpn[N][N], dpm[N][N];
int main () {
File();
for (int cases = read(); cases; -- cases) {
int n = read(), m = read(), k = read(), s = read();
dpn[0][0] = 1;
For (i, 1, k) {
For (j, 1, i)
dpn[i][j] = (dpn[i - 1][j + 1] * (j + 1) + dpn[i - 1][j - 1] * (n - j + 1)) % Mod;
dpn[i][0] = dpn[i - 1][1];
}
dpm[0][0] = 1;
For (i, 1, k) {
For (j, 1, i)
dpm[i][j] = (dpm[i - 1][j + 1] * (j + 1) + dpm[i - 1][j - 1] * (m - j + 1)) % Mod;
dpm[i][0] = dpm[i - 1][1];
}
int ans = 0;
For (a, 0, k) if ((k & 1) == (a & 1)) For (b, 0, k) if ((k & 1) == (b & 1) && a * m + b * n - 2 * a * b == s) {
ans = (ans + dpn[k][a] * dpm[k][b]) % Mod;
}
printf ("%d\n", ans);
}
return 0;
}
CS academy Binary Flips(dp)的更多相关文章
- 【gym102394B】Binary Numbers(DP)
题意:From https://blog.csdn.net/m0_37809890/article/details/102886956 思路: 可以发现转移就是右上角的一个区间前缀和 std只要开1倍 ...
- LightOJ 1033 Generating Palindromes(dp)
LightOJ 1033 Generating Palindromes(dp) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid= ...
- lightOJ 1047 Neighbor House (DP)
lightOJ 1047 Neighbor House (DP) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87730# ...
- UVA11125 - Arrange Some Marbles(dp)
UVA11125 - Arrange Some Marbles(dp) option=com_onlinejudge&Itemid=8&category=24&page=sho ...
- 【CF662C】Binary Table(FWT)
[CF662C]Binary Table(FWT) 题面 洛谷 CF 翻译: 有一个\(n*m\)的表格(\(n<=20,m<=10^5\)), 每个表格里面有一个\(0/1\), 每次可 ...
- 【POJ 3071】 Football(DP)
[POJ 3071] Football(DP) Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4350 Accepted ...
- 初探动态规划(DP)
学习qzz的命名,来写一篇关于动态规划(dp)的入门博客. 动态规划应该算是一个入门oier的坑,动态规划的抽象即神奇之处,让很多萌新 萌比. 写这篇博客的目标,就是想要用一些容易理解的方式,讲解入门 ...
- CS Academy Distinct Neighbours(经典dp)
CS Academy Distinct Neighbours(经典dp) 题意: 求相邻无相同数字的合法的排列数 题解: 题解 先将相同的数字分为一类,假设共有n组 定义\(dp[i][j]\)表示前 ...
- Tour(dp)
Tour(dp) 给定平面上n(n<=1000)个点的坐标(按照x递增的顺序),各点x坐标不同,且均为正整数.请设计一条路线,从最左边的点出发,走到最右边的点后再返回,要求除了最左点和最右点之外 ...
随机推荐
- 【学习总结】C-翁恺老师-入门-第0周<程序设计与C>
[学习总结]C-翁恺老师-入门-总 1-首先按视频说的下载编辑器 <DevC++> 并一路默认设置: 安装包下载链接 (我有vc6.0不过预感告诉我老师要用类似CS50里那种命令行编辑器? ...
- 6s ios9.0平台 微信小程序的fixed定位兼容性问题
如果不设置top和left的话 就会出现不显示问题
- Swagger2常用注解及其说明 (转)
Api 用在Controller中,标记一个Controller作为swagger的文档资源 属性名称 说明 value Controller的注解 description 对api资源的描述 hid ...
- Sqoop 使用详解(内含对官方文档的解析)
Sqoop 是 Cloudera 公司创造的一个数据同步工具,现在已经完全开源了. 目前已经是 hadoop 生态环境中数据迁移的首选,另外还有 ali 开发的 DataX 属于同类型工具,由于社区的 ...
- Percona-xtrabackup 使用详解与原理
现在有个需求需要对使用 innodb 的数据库进行热备.网上查了很多工具皆推荐 Percona-xtrabackup 于是就仔细了解调研一番. 我们可以前往 https://www.percona.c ...
- saltstack二
配置管理 haproxy的安装部署 haproxy各版本安装包下载路径https://www.haproxy.org/download/1.6/src/,跳转地址为http,改为https即可 创建相 ...
- C#中is运算符
is运算符可以检查对象是否与特定的类型兼容.“兼容”表示对象或者该类型,或者派生自该类型.例如,要检查变量是否与object类型兼容,可以使用下面的代码: int i=10; if(i is ob ...
- Java并发编程之ThreadGroup
ThreadGroup是Java提供的一种对线程进行分组管理的手段,可以对所有线程以组为单位进行操作,如设置优先级.守护线程等. 线程组也有父子的概念,如下图: 线程组的创建 public class ...
- web前端面試題
1.怎麼判斷一個一個變量的類型是string? typeof(obj)==="string" typeof obj==="string" obj.constru ...
- vue開發環境搭建
npm(node package manager),nodejs的包管理器,用於nodejs插件的安裝.卸載和管理依賴. 安裝npm: 檢查npm是否安裝成功及版本:npm -v 卸載npm: 更新n ...