[ZPG TEST 111] 奶牛的新家【DP】
3.奶牛的新家
【问题描述】
由于奶牛们纷纷表示破旧的房子实在是太丑陋了,DD决定给他们建造新家。现在有许多奶牛决定将家建造在n*m的城市中。然而奶牛们分成了k帮派,不同帮派的奶牛不能住在同列或同行上。现在DD想知道一共有多少建造方案。
【输入】
第一行三个整数n,m,k
接下来一行k个整数,分别表示每个帮派有多少只牛
【输出】
一行一个整数,建造方案数mod 100000007
【样例输入】
2 3 2
1 1
【样例输出】
12
【输入输出样例说明】
两头不同帮派的牛放在2*3的图中的方案数为12
【数据范围】
对于30%的数据,n,m≤4
对于80%的数据,n,m≤20
对于100%的数据,n,m≤30;k≤10
这是我们第二次六校联测(标题是“多校联测3”),又挂了,唉,又是死在了dp上了,烦透了。
先观察这一题,一种颜色一定是占据了若干行和若干列的,在这些行与列上是不能放别的颜色的。令g(i, j, k)表示第k种颜色恰好占据了i行j列的方案数,这里“恰好”是指这i行j列中没有哪一行或者哪一列是空的。那么有:
g(i, j, k) = C(i * j, a[k]) - sigma ( g(i', j', k) * C(i, i') * C(j, j') ),其中要满足i' < i或 j' < j,i * j要 >= a[k](a[k]表示第k种颜色的个数),C表示的是组合。
上面那条方程的意思就是,首先要加上C(i * j, a[k])表示在这i * j个格子里放a[k]个,那么有C(i * j, a[k])种方案。减掉的那一部分的意义是:某些方案并不满足这种状态(注意状态表示的是“恰好占据”),所以需要减掉这些状态。
然后f(i, j, k)表示前k种颜色,恰好占据了i行j列的方案数,那么有:
f(i, j, k) = sigma( f(i - i', j - j', k - 1) * g(i', j') * C(i, i') * C(j, j') )
#include <cstdio> const long long mod = 100000007; int n, m, K, a[15];
long long c[1005][1005], f[35][35][15], g[35][35][15], ans; int main(void) {
scanf("%d%d%d", &n, &m, &K);
for (int i = 1; i <= K; ++i) {
scanf("%d", a + i);
}
c[0][0] = 1;
for (int i = 1; i < 1001; ++i) {
c[i][0] = 1;
for (int j = 1; j <= i; ++j) {
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
} for (int k = 1; k <= K; ++k) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (i * j < a[k]) {
continue;
}
g[i][j][k] = c[i * j][a[k]];
for (int i_ = 1; i_ <= i; ++i_) {
for (int j_ = 1; j_ <= j; ++j_) {
if (i_ < i || j_ < j) {
g[i][j][k] = (g[i][j][k] - (g[i_][j_][k] * c[i][i_] % mod * c[j][j_] % mod) + mod) % mod;
}
}
}
}
}
} f[0][0][0] = 1;
for (int k = 1; k <= K; ++k) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (i * j < a[k]) {
continue;
}
for (int i_ = 1; i_ <= i; ++i_) {
for (int j_ = 1; j_ <= j; ++j_) {
f[i][j][k] = (f[i][j][k] + f[i - i_][j - j_][k - 1] * g[i_][j_][k] % mod * c[i][i_] % mod * c[j][j_]) % mod;
}
}
}
}
} for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
ans = (ans + f[i][j][K] * c[n][i] % mod * c[m][j] % mod) % mod;
}
}
printf("%d\n", (int)ans);
return 0;
}
[ZPG TEST 111] 奶牛的新家【DP】的更多相关文章
- 【BZOJ-3631】松鼠的新家 树形DP?+ 倍增LCA + 打标记
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1231 Solved: 620[Submit][Stat ...
- 3631. [JLOI2014]松鼠的新家【树形DP】
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- 刷题总结——松鼠的新家(bzoj3631)
题目: Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上. ...
- 此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist
此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist
- BZOJ 3631 【JLOI2014】 松鼠的新家
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树&q ...
- 【bzoj3631】[JLOI2014]松鼠的新家
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树"上.松 ...
- 【BZOJ3631】松树的新家 树链剖分
BZOJ3631 松树的新家 Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- 3631: [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 707 Solved: 342[Submit][Statu ...
随机推荐
- zoom to raster resolution
don't execute the ESRI's command, just find out and write codes to zoom to the raster resolution. H ...
- matlab 画图技巧
基本画图工具:matlab 画图中线型及颜色设置 matlab中坐标轴设置技巧 **Matlab中的坐标轴设置技巧** axisoff; %去掉坐标轴 axistight; ...
- 提示:“请检查浏览器代理设置”/xx-net
1.删除已导入的证书文件(运行certmgr.msc和certlm.msc,然后自己找到xxnet删),2.更新3.3.1(或是自己找到那行代码取消注释,楼下有人提及)3.删除data文件夹(下的ce ...
- 机器学习技法总结(五)Adaptive Boosting, AdaBoost-Stump,决策树
上一讲主要利用不同模型计算出来的g.採用aggregation来实现更好的g.假设还没有做出来g.我们能够採用bootstrap的方法来做出一系列的"diversity"的data ...
- Linux经常使用命令(更新中)
文件类: 1.创建目录:mkdir 例:sudo mkdir test 2.创建空文件:touch 例:sudo touch test.txt 3.删除文件:rm 删除文件不须要确认:rm -f 例: ...
- OpenCV图像处理篇之图像平滑
图像平滑算法 图像平滑与图像模糊是同一概念,主要用于图像的去噪.平滑要使用滤波器.为不改变图像的相位信息,一般使用线性滤波器,其统一形式例如以下: %20\Large%20g(i,j)=\sum_{k ...
- STM32 USB复合设备编写
目的 完成一个CDC + MSC的复合USB设备 可以方便在CDC,MSC,复合设备三者间切换 可移植性强 预备知识 cube中USB只有两个入口. main函数中的MX_USB_DEVICE_Ini ...
- ora-12541无监听的一种场景
项目上突然出现无法连接Oracle数据库的情况,提示无监听程序. 现象: 查看 listener.ora配置无问题,用Net Configuration Assistant重建监听,NCA也处于假死状 ...
- 头文件与cpp文件为什么要分开写
最表面的机制是: 头文件是程序的界面(是代码界面),提供给程序员以 类.模版.函数等一系列的声明,让程序员知道应该怎么调用里面的"东西". 从动态链接库的角度看: 头文件提供界面 ...
- 调整多个控件的dock的顺序
https://stackoverflow.com/questions/2607508/how-to-control-docking-order-in-winforms Go to View -> ...