题面:求出满足以下条件的 n*m 的 01 矩阵个数:

    (1)第 i 行第 1~li 列恰好有 1 个 1 (li+1到ri-1不能放1)

    (2)第 i 行第 ri~m 列恰好有 1 个 1。

    (3)每列至多有 1 个 1

    对于 20%的数据,n,m<=12。

    对于 40%的数据,n,m<=50。

    对于 70%的数据,n,m<=300。

    对于 100%的数据,n,m<=3000,1<=li<ri<=m。

(考试前一天晚上玩过头了,整场考试直接划水,本题打了个状压,想不出来怎么优化就跳了)

 通过对题目的初步分析 本题是一类计数问题

  那么考虑这类问题解法通常为应用计数类DP或数学模型求解(本题显然DP色彩很浓厚)

然而 无论应用实际意义,数学模型都无法推出完整的式子 那么我们就需要思考DP类做法(事实上DP也是更为通用的做法)

  常规思考 问题状态有行,列,点 很容易想出状压DP的做法f[i][j]代表进行到第i行同时第i行状态为j

然而根据数据范围状压只能拿到20pts,显然不是正解 问题在于对于较大的m无法记录其状态 这样 直接否定了对行进行状压的过程

  思考问题在于枚举同一行点的状态的时间空间复杂度无法承受 那么为我们就要尽量降低这种复杂度

一种很显然的想法是既然我们不能记录同一行点的状态 那么缩小问题 记录单个点的状态的代价显然是能接受的

  那么思路逐渐清晰 我们需要考虑问题中行或列与节点的关系

一种常规DP设计手法是根据目标设计状态,阶段与决策 那么应用到本题上 目标是求n*m矩阵在一定条件下合法放置1的不同矩阵数

倒推分解问题 得 问题实际上是行或列放置1方案数的转移

  因此 设计状态f[i][j]表示已经进行到i列 其中有j列中的1放置在右区间,那么我们最终的目标就是f[m][n];

(这道题DP设计很新颖,思维量较高,然而其本质仍然是计数类DP的设计理念:通过精确划分使得状态各决策间满足加法原理 子状态间满足乘法原理(不重不漏))

显然本题状态划分是基于左右区间的互斥性 也就是说通过分别计算当前状态左右区间合法方案数来推出当前状态合法方案数

  很容易想到对于右区间 f[i][j] = f[i - 1][j] + f[i - 1] * (r[i] - (j - 1))  <1>  //其中r[i]代表右区间在i列及其以右的区间总数 l[i]同理

而有趣的是本题左右区间计算并不是完全独立的 相反 左区间的计算正是基于右区间已知的情况下进行的 (这为我们进行DP设计,具体到状态转移提供了新思路)

公式并不难推 f[i][j] = A(i - j - l[i - 1],l[i] - l[i - 1])  <2> ;最终根据乘法原理 状态f[i][j] = <1> * <2>;

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define I int
4 #define LL long long
5 #define C char
6 #define RE register
7 #define L inline
8 const I mod = 998244353;
9 const I MAXN = 3050;
10 I n,m,l[MAXN],r[MAXN],j[MAXN],y[MAXN],f[MAXN][MAXN];
11 L I read(); L LL qpow(I,I); L LL A(I,I); L I getmin(I,I);
12 signed main(){
13 n = read(); m = read();j[0] = 1;f[0][0] = 1;
14 for(RE I i(1);i <= n; ++ i) ++l[read()],++r[read()];
15 for(RE I i(1);i <= m; ++ i) l[i] += l[i - 1],r[i] += r[i - 1];
16 for(RE I i(1);i <= m; ++ i) j[i] = 1ll * j[i - 1] * i % mod;
17 y[m] = qpow(j[m],mod - 2);
18 for(RE I i(m); i ; -- i) y[i - 1] = 1ll * y[i] * i % mod;
19 for(RE I i(1);i <= m; ++ i){
20 f[i][0] = 1ll * f[i - 1][0] * A(i - l[i - 1],l[i] - l[i - 1]) % mod;
21 for(RE I j(1);j <= getmin(n,i); ++ j)
22 f[i][j] = (f[i - 1][j] + 1ll * f[i - 1][j - 1] * (r[i] - j + 1)%mod) * A(i - j - l[i - 1],l[i] - l[i - 1]) % mod;
23 }printf("%d\n",f[m][n]);
24 }
25 L I read(){ RE I x(0); RE C z = getchar(); while(!isdigit(z)) z = getchar(); while(isdigit(z)) x = (x << 3) + (x << 1) + (z ^ 48),z = getchar(); return x; }
26 L LL qpow(I a,I b){
27 LL res(1),base(a);
28 while(b){
29 if(b & 1) res = 1ll * res * base % mod;
30 base = 1ll * base * base % mod;
31 b >>= 1;
32 }return res; }
33 L LL A(I n,I m){ if(m > n) return 0; return 1ll * j[n] * y[n - m] % mod; }
34 L I getmin(I a,I b){ return a < b ? a : b; }

总的来说本题真的是DP中一道精彩的问题 对于DP状态设计,决策都提供了较为新颖的思路 建议反复咀嚼

NOIP模拟5 T2的更多相关文章

  1. noip模拟6(T2更新

    由于蒟弱目前还没调出T1和T2,所以先写T3和T4.(T1T2更完辣! update in 6.12 07:19 T3 大佬 题目描述: 他发现katarina大佬真是太强了,于是就学习了一下kata ...

  2. NOIP 模拟4 T2

    本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...

  3. 20161003 NOIP 模拟赛 T2 解题报告

    Weed duyege的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹. 为了查出真相,duyege 准备修好电脑之后再进行一次金坷垃的模拟实验. 电脑上面有若干层金坷垃,每次只能在上面撒上一层高度为 ...

  4. 20161023 NOIP 模拟赛 T2 解题报告

    Task 2.回文串计数 (calc.pas/calc.c/calc.cpp) [题目描述] 虽然是一名理科生,Mcx常常声称自己是一名真正的文科生.不知为何,他对于背诵总有一种莫名的热爱,这也促使他 ...

  5. 20161005 NOIP 模拟赛 T2 解题报告

    beautiful 2.1 题目描述 一个长度为 n 的序列,对于每个位置 i 的数 ai 都有一个优美值,其定义是:找到序列中最 长的一段 [l, r],满足 l ≤ i ≤ r,且 [l, r] ...

  6. 神奇的NOIP模拟赛 T2 LGTB 学分块

    LGTB 学分块 LGTB 最近在学分块,但是他太菜了,分的块数量太多他就混乱了,所以只能分成3 块今天他得到了一个数组,他突然也想把它分块,他想知道,把这个数组分成3 块,块可以为空.假设3 块各自 ...

  7. 2018.02.12 noip模拟赛T2

    二兵的赌注 Description游戏中,二兵要进入了一家奇怪的赌场.赌场中有n个庄家,每个庄家都可以猜大猜小,猜一次一元钱.每一次开彩前,你都可以到任意个庄家那里下赌注.如果开彩结果是大,你就可以得 ...

  8. ztz11的noip模拟赛T2:查房

    链接: https://www.luogu.org/problemnew/show/U46611 思路: 这道题告你n-1条边就是骗你的 部分分也是骗你的 这道题连对边5分钟的事 一个点对另一个点有影 ...

  9. 2018.10.30 NOIp模拟赛T2 数字对

    [题目描述] 小 H 是个善于思考的学生,现在她又在思考一个有关序列的问题.        她的面前浮现出一个长度为 n 的序列{ai},她想找出一段区间[L, R](1 <= L <= ...

  10. NOIP模拟18 T2

    不知道为什么很多人拒绝这题打搜索...其实搜索在充分剪枝后时间是非常优秀的,不管数据怎样基本都可跑出 首先一个显然结论:对于某种状态,他抓到的小精灵一定是一个连续的区间. 因此我们可以枚举这个区间的左 ...

随机推荐

  1. Weekly Contest 138

    1051. Height Checker Students are asked to stand in non-decreasing order of heights for an annual ph ...

  2. 14- 小程序测试与airtest自动化测试

    什么是小程序 小程序是一种不需要下载安装即可使用的应用,它实现了应用"触手可及"的梦想,用户扫一扫或者搜一下即可打开应用.也体现了"用完即走"的理念,用户不用关 ...

  3. 06- 移动端APP兼容性测试以及APP兼容性测试手机选择与云测试技术

    在开始测试APP之前,应该考虑什么问题?或者如何选择设备?多少部手机测试兼容性最佳? 兼容性测试手机数量:主测手机 1 ,2(根据人员),辅助测试手机:用于兼容性测试.(50-60台最佳,至少5-20 ...

  4. hdu3768 spfa+全排列

    题意:       给你一个无向图,和一些必须经过的点,问你从起点出发,到达所有必须经过的点再回来的最小总路径. 思路:       因为必须经过的点的数量很小,小于等于10,全排列是 10! = 3 ...

  5. hdu1024 最大m子序列和

    题意:      给你一个序列n个数组成,然后让你在里面找到m个子序列,让这m个子序列的和最大. 思路:       dp[i][j]表示的是第j个数字在第i个子序列时的当前最优值. dp[i][j] ...

  6. hdu2276 矩阵构造

    题意:      给了n个灯泡的状态,他们绕成一个环,0是灭,1是亮,每一秒灯泡的状态都会改变,规则是如果当前这个灯泡的左边的灯泡当前是状态1,那么下一秒当前的这个灯泡状态就改变0变1,1变0,最后问 ...

  7. 利用 ROP 技术绕过 DEP 保护的一次简单尝试

    \x 01 前言 DEP是数据执行保护的英文缩写,全称为Data Execution Prevention.数据执行保护(DEP) 是一套软硬件技术,能够在内存上执行额外检查以帮助防止在系统上运行恶意 ...

  8. 启动spring boot项目时报错:java.lang.ClassNotFoundException: javax.servlet.Filter

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定

    如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了.我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础.最开始接触 ...

  10. springboot国际化与@valid国际化支持

    springboot国际化 springboot对国际化的支持还是很好的,要实现国际化还简单.主要流程是通过配置springboot的LocaleResolver解析器,当请求打到springboot ...