那天和机房的同学们一起想了很久,然而并没有做出来……今天看了题解,的确比较巧妙,不过细细想来其实规律还是比较明显,在这里记录一下~

  当天自己做的时候,主要想到的是两点 : 1.按列dp 2.对行进行排序。虽然没有做出来,但做法的确和这两点是重合的。我们考虑强制满足左端点,然后 dp 右端点的方法,记录状态 \(f[i][j][k]\) 为 dp 到第 \(i\) 列时,有 \(j\) 列是空的,且还有 \(k\) 个右端点没有满足(这 \(k\) 个右端点的位置均 \(<= i\))。

  首先从 \(i\) 转移到 \(i + 1\) 的条件就是 \(j + 1 >= b[i + 1]\) 其中 b 数组存的是以 \(x\) 为左端点的行数。这样做的本质就是将行按照左端点从小到大排序之后依次满足,端点为 \(x\) 的就强制在转移到第 \(x\) 列的时候去进行考虑(一方面一定要满足,另一方面可以放的范围已经限制了)。转移的时候我们分成三种情况:强制第 \(i\) 列不放 / 放一个满足左端点,满足一个右端点和放在一个空白的位置。对于后面两种转移,只有当 \(j >= b[i + 1]\) 时才会发生(说明我们可以选择将多出来的这一行去用于满足右端点 、放在空白)。这样就只需要讨论一下满足的是哪一个右端点和空白,对于一起转移的满足的左端点乘上排列数以统计不同的方案就可以了。

  很棒的题,奈何自己太弱啦……加油ヾ(◍°∇°◍)ノ゙

#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define maxn 205
#define int long long
int n, m, a[maxn], b[maxn], c[maxn];
int ans, f[maxn][maxn][maxn];
int fac[maxn], P[maxn][maxn]; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} void pre()
{
for(int i = ; i <= m; i ++) P[i][] = ;
for(int i = ; i <= m; i ++)
for(int j = ; j <= i; j ++)
P[i][j] = (P[i - ][j - ] + P[i - ][j]) % mod;
fac[] = ;
for(int i = ; i <= m; i ++) fac[i] = fac[i - ] * i % mod;
for(int i = ; i <= m; i ++)
for(int j = ; j <= i; j ++)
P[i][j] = P[i][j] * fac[j] % mod;
} void Up(int &x, int y) { x = (x + y) % mod; } void DP()
{
f[][][] = ;
for(int i = ; i < m; i ++)
for(int j = ; j <= i; j ++)
for(int k = ; k <= n; k ++)
{
if(!f[i][j][k]) continue;
if(j + >= b[i + ])
{
int tem = f[i][j][k] * P[j + ][b[i + ]] % mod;
Up(f[i + ][j + - b[i + ]][k + c[i + ]], tem);
}
if(j >= b[i + ])
{
int tem = f[i][j][k] * a[i + ] % mod * P[j][b[i + ]] % mod;
Up(f[i + ][j - b[i + ]][k + c[i + ]], tem);
if(k + c[i + ])
{
tem = f[i][j][k] * (k + c[i + ]) % mod * P[j][b[i + ]] % mod;
Up(f[i + ][j - b[i + ]][k + c[i + ] - ], tem);
}
}
}
} signed main()
{
n = read(), m = read();
for(int i = ; i <= n; i ++)
{
int l = read(), r = read();
for(int j = l + ; j <= m - r; j ++) a[j] ++;
b[l] ++, c[m - r + ] ++;
}
pre(); DP();
for(int i = ; i <= m; i ++) Up(ans, f[m][i][]);
printf("%lld\n", ans);
return ;
}

【题解】51nod1327 棋盘游戏的更多相关文章

  1. 题解-bzoj3901 棋盘游戏

    2019年第一篇文章 (。・∀・)ノ゙ Problem bzoj无良权限题,拿学长的号交的 题目概要:给定一个\(n\times n\)的矩阵.令\(x=\frac {n+1}2\).可以进行任意次以 ...

  2. 51nod1327 棋盘游戏

    远古大坑 神仙DP状态设计题 https://blog.csdn.net/white_elephant/article/details/83592103 从行的角度入手,无论如何都要状压 每列最多放一 ...

  3. 1358 棋盘游戏[状压dp]

    1358 棋盘游戏  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 大师 Master 题解  查看运行结果     题目描述 Description 这个游戏在一个有10*10 ...

  4. HDU1281: 棋盘游戏(二分图匹配)

    棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. LOJ 一本通一句话题解系列:

    第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...

  6. HDU1281 棋盘游戏 —— 二分图最大匹配 + 枚举

    题目链接:https://vjudge.net/problem/HDU-1281 棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit ...

  7. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  8. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  9. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

随机推荐

  1. Java基础知识总结一

    1.何为编程? 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程. 为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路.方法.和手段通过计算机能够理解 ...

  2. photoshop cc 2018安装破解教程(破解补丁,亲测,绝对可用)

    破解步骤说明:下载地址百度网盘,https://pan.baidu.com/s/1cWtpUesl2fms3tFwEC0MiQ 1.右键解压Adobe Photoshop CC 2018 64位这个文 ...

  3. .NET邮件发送详情

    ①百度下载个Free Smtp Server ②下载完成后,打开进去,点击左上角的options,弹出窗口,进行如下图选项即可(一般默认已正确选中),然后我们可以把这软件关了. (下次你重启电脑时,也 ...

  4. TPO-12 C1 Revise a Hemingway paper

    TPO-12 C1 Revise a Hemingway paper 第 1 段 1.Listen to a conversation between a student and a professo ...

  5. 了解Python控制流语句——for 循环

    for 循环 Python教程中for...in 语句是另一种循环语句,其特点是会在一系列对象上进行迭代(Iterates),意即它会遍历序列中的每一个项目.我们将在后面的Python序列(Seque ...

  6. Python全栈 Web(边框、盒模型、背景)

    原文地址 https://yq.aliyun.com/articles/634926 ......................................................... ...

  7. 解决ssh_exchange_identification:read connection reset by peer 原因

    服务器改了密码,试过密码多次后出现: ssh_exchange_identification: read: Connection reset by peer 可以通过ssh -v查看连接时详情 Ope ...

  8. VBS简明教程

    VBS简明教程   一.输出 VBS的输出使用函数Msgbox调用对话框进行输出. Msgbox(message) Message为要输出的信息 二.输入 VBS的输入,调用函数Inputbox()进 ...

  9. RDL/RDLC批量单据打印 [转]

    RDL/RDLC批量单据打印 使用RDL或RDLC进行单据打印时,单张单据打印比较直观简单,无需说明.下面我们来谈一下批量单据打印的实现方法.以下以RDL的ReportBuilder设计环境为例进行讲 ...

  10. Fluent Python: @property

    Fluent Python 9.6节讲到hashable Class, 为了使Vector2d类可散列,有以下条件: (1)实现__hash__方法 (2)实现__eq__方法 (3)让Vector2 ...