题目描述
译自 JOISC 2018 Day1 T3「テント / Tents」
JOI 君经营着一座露营地。露营地被划分为 H 行 W 列的矩阵,各行平行于东西方向,而各列平行于南北方向。从北向南数第 i i i 行和从东向西数第 j j j 列相交的格子表示为 ( i , j ) (i,j) (i,j)。

JOI 君想在格子里搭一些帐篷。每座帐篷必须占据刚好一个格子。没有两座帐篷会占据同一个格子。

每座帐篷在东、南、西、北四个方向之一有一个出入口。帐篷的出入口朝向必须满足以下条件:

如果格子 ( i 1 , j ) 和 ( i 2 , j ) ( 1 ≤ i 1 < i 2 ≤ H , 1 ≤ j ≤ W ) (i_{1},j) 和 (i_{2},j)(1\le i_{1} < i_{2}\le H,1\le j\le W) (i1​,j)和(i2​,j)(1≤i1​<i2​≤H,1≤j≤W) 上都有帐篷,那么格子 ( i 1 , j ) (i_{1},j) (i1​,j) 上的帐篷出入口必须朝南,而格子 (i_{2},j) 上的帐篷出入口必须朝北。
如果格子 ( i , j 1 ) 和 ( i , j 2 ) ( 1 ≤ i ≤ H , 1 ≤ j 1 < j 2 ≤ W ) (i,j_{1}) 和 (i,j_{2})(1\le i\le H,1\le j_{1} < j_{2}\le W) (i,j1​)和(i,j2​)(1≤i≤H,1≤j1​<j2​≤W) 上都有帐篷,那么格子 ( i , j 1 ) (i,j_{1}) (i,j1​) 上的帐篷出入口必须朝东,而格子 ( i , j 2 ) (i,j_{2}) (i,j2​) 上的帐篷出入口必须朝西。
JOI 君想知道在露营地上搭起至少一顶帐篷的合法方案数。两种方案被认为是不同的,当且仅当有至少一个格子的状态(即是否存在帐篷或帐篷出入口的朝向)不同。

任务
给出露营地的相关信息,请求出在露营地上搭起至少一顶帐篷的合法方案数,对 1000000007 取模。

输入格式
仅一行两个以空格分开的整数 H 和 W,表示 JOI 君经营的露营地有 H 行 W 列。

输出格式
输出一行,仅一个整数,表示在露营地上搭起至少一顶帐篷的合法方案数对 1000000007 取模的余数。

分析:如果某一行有两顶帐篷,这两顶帐篷出口必须东西相对,那么这两顶帐篷所在的列不可能有其它帐篷(因为要求出口南北相对)。基于此,可以进行一个dp:

假设我们从上往下一行一行放帐篷。设大小为 ( i , j ) (i,j) (i,j)的营地的方法为 f [ i ] [ j ] f[i][j] f[i][j]
在计算 f [ i ] [ j ] f[i][j] f[i][j]时,不妨分类讨论:
(1)这一行是空的。这种情况有 f [ i − 1 ] [ j ] f[i-1][j] f[i−1][j]种放法。
(2)这一行只有一顶帐篷,且这顶帐篷所在列也只有一顶帐篷。我们先把这一行的帐篷放好,有 4 ∗ j 4*j 4∗j种放法(算上方向)。那么这顶帐篷所在行列都不能放帐篷了,剩下 i − 1 i-1 i−1行和 j − 1 j-1 j−1列,因此总放法为 4 ∗ j ∗ f [ i − 1 ] [ j − 1 ] 4*j*f[i-1][j-1] 4∗j∗f[i−1][j−1]。
(3)这一行有一顶帐篷,且这一列的前面某行也有一顶帐篷,这两顶帐篷南北相对。这一顶帐篷的放法有 j j j种,前面行帐篷的方法有 i − 1 i-1 i−1种。把这两顶帐篷放好后,这两行一列就不能再放帐篷,剩下的放法为 f [ i − 2 ] [ j − 1 ] f[i-2][j-1] f[i−2][j−1]。因此总贡献为 j ∗ ( i − 1 ) ∗ f [ i − 2 ] [ j − 1 ] j*(i-1)*f[i-2][j-1] j∗(i−1)∗f[i−2][j−1]。
(4)这一行有两顶帐篷,则帐篷所在的两列不能有其它帐篷。同理,总贡献为 j ( j − 1 ) 2 f [ i − 1 ] [ j − 2 ] \frac{j(j-1)}{2}f[i-1][j-2] 2j(j−1)​f[i−1][j−2]。

注意这样算出的结果可能全空,因此最后答案要减1。

代码:

#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<vector>
#define mod 1000000007
using namespace std;
typedef long long ll;
int read() {int x=0,f=1;char ch=getchar();while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}while(ch>='0' && ch<='9') {x=10*x+ch-'0';ch=getchar();}return x*f;
}
const int Size=3005;
const int INF=0x3f3f3f3f;
const int MOD=10007;
int n,m,dp[Size][Size];
int main() {n=read();m=read();for(int i=0; i<=n; i++)  dp[i][0]=1;for(int i=0; i<=m; i++)  dp[0][i]=1;for(int i=1; i<=n; i++) {for(int j=1; j<=m; j++) {dp[i][j]=dp[i-1][j];dp[i][j]=(dp[i][j]+4ll*j%mod*dp[i-1][j-1]%mod)%mod;if(j>=2)  dp[i][j]=(dp[i][j]+(ll)j*(j-1)/2%mod*dp[i-1][j-2]%mod)%mod;if(i>=2)   dp[i][j]=(dp[i][j]+(ll)j*(i-1)%mod*dp[i-2][j-1]%mod)%mod;}}printf("%d",(dp[n][m]-1+mod)%mod);return 0;
}

LOJ#2833 「JOISC 2018 Day 1」帐篷 dp相关推荐

  1. LOJ #2838. 「JOISC 2018 Day 3」比太郎的聚会 根号分治

    这道题的数据范围中有两个需要注意到的点: 1. 边都是由编号小的点连向编号大的点. 2. 总点数只有 $10^5$ 个. 所以我们可以考虑采取根号分治的做法: 对于点数大于 $\sqrt n$ 的部分 ...

  2. [LOJ]#2838. 「JOISC 2018 Day 3」比太郎的聚会 根号分治

    Solution 以后不会做题还是要考虑根号分治啊-- 对于给出点数≥n\ge\sqrt n≥n​,直接O(n)O(n)O(n)DP: 对于给出点数<n<\sqrt n<n​,可以预 ...

  3. 「JOISC 2018 Day 3」比太郎的聚会

    「JOISC 2018 Day 3」比太郎的聚会 题意: ​ 给你一个\(DAG\),若干组询问,每次给出一个终点和若干个点,问从给出点以外的点出发,到达终点的最长路.(\(|V|\leq 1e5 | ...

  4. @loj - 6353@「CodePlus 2018 4 月赛」组合数问题 2

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 请你找到 k 个不同的组合数,使得对于其中任何一个组合数 \(C ...

  5. LOJ #2878. 「JOISC 2014 Day2」邮戳拉力赛 动态规划+括号序列

    神题呀,我们观察到行走的方式一定是一条链+若干条环. 然后环可以看成是一对括号,所以来一个基于括号序的 DP. code: #include <bits/stdc++.h> #define ...

  6. [LOJ#2878]. 「JOISC 2014 Day2」邮戳拉力赛[括号序列dp]

    题意 题目链接 分析 如果走到了下行车站就一定会在前面的某个车站走回上行车站,可以看成是一对括号. 我们要求的就是 类似 代价最小的括号序列匹配问题,定义 f(i,j) 表示到 i 有 j 个左括号没 ...

  7. 「JOISC 2016 Day 3」回转寿司

    https://loj.ac/problem/2736 题解 挺有意思的题. 考虑这种操作不好直接维护,还有时限比较长,所以考虑分块. 考虑一个操作对整个块的影响,无非就是可能把最大的拿走,再把新的元 ...

  8. LOJ6299:「CodePlus 2018 3 月赛」白金元首与克劳德斯 (离散化+前缀和)

    题目传送门:https://loj.ac/problem/6299 题目分析:一道不难的题目,然而比赛的时候只有90pts.由于所有克劳德斯(clouds)一开始都不相交,所以答案不是1就是2.用O( ...

  9. LOJ #510. 「LibreOJ NOI Round #1」北校门外的回忆(倍增+动态开点线段树)

    题目 这个题是一个精彩的分析性质区间离散的问题 真的详细 维护链真的一绝. LOJ\rm LOJLOJ最短ACCode\rm AC \ CodeAC Code #include<bits/std ...

最新文章

  1. python读取caffemodel文件
  2. CSP认证201512-1 数位之和[C++题解]:模拟、水题
  3. C语言文件读写(5)-文件位置相关
  4. 音视频技术开发周刊 | 157
  5. 24小时学通Linux内核之构建Linux内核
  6. Java中“/”,“.”所代表的文件路径
  7. 解决:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal
  8. 基于openvswitch+Docker构建SDN网络测试环境 (使用ovs-docker进行构建)
  9. 疑似华为P50系列7月29日发布:麒麟9000旗舰芯片加持
  10. require.js引入css文件,[DikeJS]RequireJS引入CSS样式文件(五)
  11. 使用WITH AS提高性能简化嵌套SQL
  12. 解决jQgrid 设置列宽度自动调整时, 出现滚动条问题.
  13. VB2010(24)窗体用户控件
  14. Loadrunner11安装
  15. 图书管理系统-借书操作
  16. 微信小程序地图和百度地图定位位置不一样
  17. IBM Websphere CEI Configuration
  18. 用python输出世界你好_Hello World! (你好,世界!)
  19. OSPO Summit 2022 正式启动!OSPO Summit 2022 Launched!
  20. 电子信息类和计算机类专业网课表

热门文章

  1. Three.js入门——画星空(star field)
  2. 【XBL 无法开机问题】【工位机调试】sdm660 XBL阶段,绕过电池在位检测,强制启动
  3. java旅游管理面试,旅游管理面试题目
  4. 2019-8-24 小米商城商品展示界面
  5. 成都榆熙:拼多多产地直发模式如何解决了流通环节多的问题?
  6. css里外边框与内边框_基本CSS边框
  7. win10戴尔游侠GTX1050TI+TensorFlow-gpu+CUDA10.0.130+CUDNN7.4.1.5配置深度学习环境
  8. Spider爬虫--手机App抓包爬虫
  9. 今日头条-新年集卡分2亿,每晚8:45红包雨
  10. 大学计算机基础知识点图文,大学计算机基础知识点分布最新版