时间限制 3000 ms 内存限制 65536 KB

题目描述

廖神和男神在植树节的时候准备玩一个奇怪的游戏,他们现在有一个被分割成n*n个格子的矩形土地,他们现在准备往这个地里种树,但这个种树游戏必须满足以下两个要求:

1.每个格子只能是不种树(“0”)或种树(“1”)
2.每行和每列只能种两棵树
现在了不起的廖神种了之前的m行,他邀请男神种完剩下的树。可是男神很懒,这种事他一般都是交给学弟来做,那么聪明的你知道一共有多少种不同的填法吗?

输入格式

第一行是3个整数n,m,mod (2≤n≤500, 0≤m≤n, 2≤mod≤10^9).接下来的m行每行包含n个字符,每行有且仅有2个'1'表示已经种过树了,其余全为'0',表示没有种过树,而给出的每一列上至多有2个1,则廖神会使得他种过的树符合规定. 多组数据, 以EOF结束

输出格式

输出男神能够种果树的方案数 模mod的余数.

输入样例

3 1 1000
011

输出样例

2

分析

这个数据大小就要n2以内的时间复杂度,这样肯定不能搜索。前m行按要求种好了,现在要种的矩形土地里某些列不能种了,某些只能种一棵,剩下的必须种两棵。

我们一行行来种。每种一行,就会出现下面三种状态转移:

i表示能种一棵树的列数,j表示能种两棵树的列数。

1. 选择i列中的两列,i,j 变成 i-2,j。

2. 选择i列和j列的各一列,因为j的某列种了一棵树,这列就变成只能种一棵树的列,所以i,j变成 i,j-1。

3. 选择j中两列,i,j变成i+2,j-2。

dp[k][i][j]表示种完第k行,有i列能种一棵树,j列能种两棵树的方案数。那么就有

dp[k][i][j]+=dp[k-1][i+2][j]*C(i+2,2) 表示k-1行种好后,选择只能种一棵的i+2列里的两列。

dp[k][i][j]+=dp[k-1][i][j+1]*C(i,1)*C(j+1,1) 表示选择i列和j+1列中的各一列。

dp[k][i][j]+=dp[k-1][i-2][j+2]*C(j+2,2) 表示选择j+2列里的两列。

这样最后的dp[n][0][0]就是我们的答案了。

转移时,k在增大。

所以可以这样写循环:

for(k:m+1 to n)

  for(j:0 to b)//j最大就是b了,不可能变大。

    for(i: 0 to n)//为什么是n呢,因为如果先种j列中的列,那么i就在增大,可以大于a,最大到n。

    {...}

能不能减少维数呢?

能种两棵的列往减小或相同的方向转移,即j+1、j+2、j转移到j。

且j相同时,i往小的方向转移,所以我们可以去掉代表第几行的那一维,然后循环这样写:

for(j:b downto 0)

    for(i: n downto 0)

    {...}

一开始dp[a][b](a列能种一棵树,b列能种两棵树。)=1。

代码

#include<cstdio>
#include<cstring>
#define N 550
#define ll long long
int dp[N][N];
int a,b,v[N];
int n,m,mod;
char s[N];
int main()
{
while(~scanf("%d%d%d",&n,&m,&mod))
{
memset(dp,,sizeof dp);
memset(v,,sizeof v);
b=n;
a=;
for(int i=; i<=m; i++)
{
scanf("%s",s);
for(int j=; j<n; j++)
if(s[j]=='')
{
v[j]++;
if(v[j]==)
a--;
else
{
b--;
a++;
}
}
}
dp[a][b]=;
for(int j=b; j>=; j--)
for(int i=n; i>=; i--)
if(i!=a||j!=b)
{
if(i>=)
dp[i][j]+=(ll)(j+)*(j+)/ *dp[i-][j+]%mod;
if(dp[i][j]>=mod)
dp[i][j]-=mod; dp[i][j]+=(ll)i*(j+)*dp[i][j+]%mod;
if(dp[i][j]>=mod)
dp[i][j]-=mod; dp[i][j]+=(ll)(i+)*(i+)/ *dp[i+][j]%mod;
if(dp[i][j]>=mod)
dp[i][j]-=mod;
}
printf("%d\n",dp[][]);
}
return ;
}

  

【kAri OJ】621. 廖神的树的更多相关文章

  1. 【kAri OJ 616】Asce的树

    时间限制 1000 ms 内存限制 65536 KB 题目描述 作为一个东北大老爷们,大A熊以力气大著称,现在有一颗半径为r的树,剖面图如黑色的圆,大A熊决定搬几个半径为R的圆柱形桶将其围住,剖面图如 ...

  2. 【九度OJ】题目1176:树查找 解题报告

    [九度OJ]题目1176:树查找 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1176 题目描述: 有一棵树,输出某一深度的所有节点 ...

  3. 【kAri OJ】wzt的树

    时间限制 1000 ms 内存限制 65536 KB 题目描述 改革春风吹满地,中国人民真争气!家庭联产承包责任制以后,全国人民争想发家致富.wzt于是包了一个山头来种植金丝楠木,花了好几年种了N棵树 ...

  4. Light OJ 1114 Easily Readable 字典树

    题目来源:Light OJ 1114 Easily Readable 题意:求一个句子有多少种组成方案 仅仅要满足每一个单词的首尾字符一样 中间顺序能够变化 思路:每一个单词除了首尾 中间的字符排序 ...

  5. 【kAri OJ605】陈队的树

    时间限制 1000 ms 内存限制 65536 KB 题目描述 陈队有N棵树,有一天他突然想修剪一下这N棵树,他有M个修剪器,对于每个修剪器给出一个高度h,表示这个修剪器可以把某一棵高度超过h的树修剪 ...

  6. [Swust OJ 763]--校门外的树 Plus(暴力枚举)

    题目链接:http://acm.swust.edu.cn/problem/0763/ Time limit(ms): 1000 Memory limit(kb): 65535 西南某科技大学的校门外有 ...

  7. SHU oj 422 风力观测 线段树

    风力观测 发布时间: 2017年7月9日 18:17   最后更新: 2017年7月9日 21:04   时间限制: 1000ms   内存限制: 128M 描述 小Y正在观测y地区的风力情况,他在一 ...

  8. 【LOJ】#6391. 「THUPC2018」淘米神的树 / Tommy

    题解 一道非常神仙的计数题 如果只有一个点,就是非常简单的树型dp \(f_{u} = (siz_{u} - 1)! \prod_{v \in son_{u}} \frac{f_{v}}{siz_{v ...

  9. 浴谷金秋线上集训营 T11738 伪神(树链剖分)

    先树链剖分,一棵子树的编号在数组上连续,一条链用树链剖分,把这些线段全部取出来,做差分,找到有多少点被>=t条线段覆盖即可. #include<iostream> #include& ...

随机推荐

  1. unity3D里面的点乘和叉乘

    在unity3D里面.两个向量的点乘所得到的是两个向量的余弦值,也就是-1 到1之间,0表示垂直,-1表示相反,1表示相同方向. 两个向量的叉乘所得到的是两个向量所组成的面的垂直向量,分两个方向. 简 ...

  2. yum报错:Error: xz compression not available

    测试服务器(centos6.5)经过一段时间的折腾,有一天在上面进行yum操作时突然出现下面的报错: Error: xz compression not available 最后经过一番排查,发现原因 ...

  3. flex布局滑动页面

    html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  4. Bitbucket免费的私有仓库

    1.官网 https://bitbucket.org/ 2.介绍 知乎:http://www.zhihu.com/question/20053312 建议同时用Bitbucket和Github,理由如 ...

  5. Django1.10环境安装

    在Ubuntu14上 一 安装脚本 wget https://github.com/django/django/archive/master.tar.gz apt-get install python ...

  6. Camera中对焦模式总结

    1,相机对焦模式有以下几种: auto  //自动 infinity //无穷远 macro //微距 continuous-picture //持续对焦 fixed //固定焦距   2,常见对焦模 ...

  7. android Camera 录像时旋转角度

    录像保存时,旋转角度要与所拍录像时的角度保持一致,否则,看起来就会出现角度不度,巅倒等问题. 一般在开始录像之前会先去初始化录像 initializeRecorder 中会去读取当前的录像或拍照的旋转 ...

  8. 变态跳台阶-一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

    class Solution { public: int jumpFloorII(int number) { ) ; ) ; *jumpFloorII(number-); } };

  9. java中从1970-1-1到当前时间之间的毫秒数转换为oracle date

    java中System.currentTimeMillis()取到的是从1970-01-01 00:00:00.000到当前时间的毫秒数,一个long类型的值. 现在oracle数据库中某表中存取的是 ...

  10. use AP_VENDOR_PUB_PKG.Update_Vendor_Site_Public to u ORA-01722: invalid number in Package AP_VENDOR_PUB_PKG Procedure Update_Vendor_Site_Public

    ORA-01722: invalid number in Package AP_VENDOR_PUB_PKG Procedure Update_Vendor_Site_Public 发现此问题的经过: ...