前置技能点:DP,上升子序列

如果你不知道上面的东西,请先行了解

start_of_题面

【问题描述】

被诅咒的监狱里流淌着囚人们的歌谣。
将罪恶的青春全部抹杀殆尽。
“看守”执掌“囚犯”的生杀大权。
“囚犯”中藏着可以杀掉“看守”的恶魔。
这就是,将人性扭曲的,“监狱游戏”。

监狱游戏的参加者被分为了看守和囚犯,两侧各 n n n人。举行监狱游戏的地点在一个被改造过了的大仓库一样的地方,里面有两排共 2 n 2n 2n个房间,服务入口侧的是囚犯的房间,行刑室侧的是看守的房间。如下图所示

相邻的看守与囚犯的房间之间可以通过对讲机互相沟通,但是声音会被处理,无法辨别。两侧的分类房中都有一排各n扇门,从左到右编号为 1 ∼ n 1 ∼ n 1∼n。进入一扇门之后会有一条狭长、黑暗,而且弯弯曲曲的走廊通向房间。由于其特殊的构造,看守的i号门对应房间未必就是囚犯的i号门对应的房间。因此,想在这个监狱游戏中胜出,了解门与门之间的对应关系是很有必要的。

接下来的问题就和监狱游戏没有太多关系了。我们令 a [ i ] a[i] a[i]表示看守的第i扇门对应囚犯的哪一扇门。令图G为有n个节点的图,编号为 1 ∼ n 1 ∼ n 1∼n。对于满足 1 ≤ i &lt; j ≤ n 1 ≤ i &lt;j ≤ n 1≤i<j≤n一对 i i i和 j j j,如果有 a [ i ] &gt; a [ j ] a[i] &gt; a[j] a[i]>a[j],那么在 G G G中编号为 i i i和 j j j的节点之间连一条边。得到的图 G G G被称为逆序图。

对于图 G = ( V , E ) G = (V, E) G=(V,E),非空点集 S ∈ V S ∈ V S∈V是一个独立集当且仅当对于任意两个点 u , v ∈ V u, v ∈ V u,v∈V,不存在 u , v ∈ E u, v ∈ E u,v∈E。而 S S S是一个覆盖集当且仅当对于任意点 v ∉ S v ∉ S v∈/​S存在点 u ∈ S u ∈ S u∈S满足 u , v ∈ E u, v ∈ E u,v∈E。

我们在意的是,图 G G G中有多少个点集既是独立集又是覆盖集。出于某种不知
名的原因,被迫参加监狱游戏的大家的安危和这个问题的答案有关。拜托了,请
一定要求出这个方案数。

【输入格式】

输入第一行含有两个整数 n n n和 m m m,表示逆序图的点数和边数。
接下来 m m m行,每行描述一条边。每行包含两个 1 ∼ n 1 ∼ n 1∼n的整数,代表边的两个
端点。保证没有重边和自环。保证给定的图是一个合法的逆序图,即,存在至少一个序列,按照题目描述中所述方法得到的逆序图是给定的图。

【输出格式】

输出一个整数,表示方案数对 1 , 000 , 000 , 007 1,000,000,007 1,000,000,007取模得到的结果。

【样例输入】

5 5
2 2
2 5
1 4
3 4
3 5

【样例输出】

3

【样例解释】

样例中的逆序图如下图所示:

序列 2 , 4 , 5 , 1 , 3 {2,4,5,1,3} 2,4,5,1,3的逆序图即为此图。满足条件的点集有{ 1 , 2 , 3 1,2,3 1,2,3}、{ 1 , 5 1,5 1,5}和{ 4 , 5 4,5 4,5}。
可以证明不存在其他满足条件的点集。

【数据规模和约定】
对于 20%的数据, n ≤ 20 n ≤ 20 n≤20。
对于 60%的数据, n ≤ 100 n ≤ 100 n≤100。
对于 100%的数据, n ≤ 1000 n ≤ 1000 n≤1000, 0 ≤ m ≤ n ( n − 1 ) 2 0 ≤ m ≤ \frac{n(n-1)}{2} 0≤m≤2n(n−1)​。

end_of_题面

先说一句,题面有毒

然后看题,发现之前做过一道类似的,那道题的图也是一样的规则,问题是求最大独立集,显然这样就是直接一个最长上升子序列就可以了。

回到这道题,首先要求是一个最大独立集,所以肯定是一个上升序列,有要求是一个覆盖集,也就是说每一个没有选的点,必须至少和一个选了的点连边,所以这个上升序列的最后一个的右侧不能有比它大的元素,这样是不合法的,所以我们要求的是极长上升子序列

我们可以以 f [ i ] f[i] f[i]表示以 i i i结尾的方案数,如果它可以转移到 f [ j ] f[j] f[j],则需要满足两个条件,一个是 a [ j ] &gt; a [ i ] a[j]&gt;a[i] a[j]>a[i],另一个是 m i n { a [ k ] } &gt; a [ j ] ( i &lt; k &lt; j 且 a [ k ] &gt; a [ i ] ) min \{a[k]\} &gt; a[j](i &lt; k &lt; j 且a[k]&gt;a[i]) min{a[k]}>a[j](i<k<j且a[k]>a[i]),但是这样不太好统计答案,所以我们加一位 a [ n + 1 ] = n + 1 a[n+1]=n+1 a[n+1]=n+1,并且规定必须选它,这样答案就变成了 f [ n + 1 ] f[n+1] f[n+1]

对于把图转换成序列,可以直接用拓扑排序

start_of_code

#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;#define LL long longconst int mod = 1000000007;LL n, m, ans = 0;
LL In[1010], a[1010], f[1010];
struct cmp{bool operator()(int a, int b){return a < b;}
};
priority_queue<int, vector<int>, cmp> q;
vector<int> e[1010];namespace file{inline void open(){freopen("senritsu.in", "r", stdin);freopen("senritsu.out", "w", stdout);}inline void close(){fclose(stdin);fclose(stdout);}
}namespace input{inline LL read(){LL a = 0;LL f = 1;char ch;while(!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')));if(ch == '-')f = -1;else{a = a * 10;a += ch - '0';}while((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')){a = a * 10;a += ch - '0';} return a * f;}
}int main()
{file::open();n = input::read(), m = input::read();for(int i = 1;i <= m;++i){int x = input::read(), y = input::read();if(x > y)swap(x, y);e[x].push_back(y);++In[y];}for(int i = 1;i <= n;++i)if(In[i] == 0)q.push(i);int Top = n;while(!q.empty()){int f = q.top();q.pop();a[f] = Top;--Top;int s = e[f].size();for(int i = 0;i < s;++i){int v = e[f][i];--In[v];if(!In[v])q.push(v);}}a[0] = 0, a[n + 1] = n + 1;f[0] = 1;for(int i = 0;i <= n;++i){int r = n + 2;for(int j = i + 1;j <= n + 1;++j){if(a[j] < a[i] || a[j] >= r)continue;f[j] += f[i];if(f[j] >= mod)f[j] -= mod;r = a[j];}}printf("%lld\n", f[n + 1] % mod);file::close();return 0;
}

end_of_code

4-4模拟赛 囚人的旋律——DP相关推荐

  1. 【bzoj4715】囚人的旋律 dp

    题目描述 给你一个 $1\sim n$ 的排列 $a_i$ ,若 $i\le j$ 且 $a_i\ge a_j$ ,则 $i$ 到 $j$ 有一条边.现在给你这张图,求既是独立集(任意两个选定点都没有 ...

  2. [GDOI模拟2015.08.12]囚人的旋律

    题目大意 给定一个点数为 n n,边数为mm的图 G=(V,E) G=(V,E),改图的生成m满足存在一个 1 1至nn的排列 a1..an a_{1}..a_{n},使得: ∙∀(u,v)∈E,u& ...

  3. NOIP2013模拟10.23囚人的旋律

    题目大意 给定一个逆序图,表示若a[i]>a[j](i<j)那么i向j连一条边(这里是给定边数),问有多少个选点方案,是的选定的点之间没有连边,没选定的点与选定的点中至少一个点有连边. 由 ...

  4. 【BZOJ4715】囚人的旋律

    题解: 思考了很久这个图的特点没有发现 看了题解瞬间醒悟原来要在序列上做 还原出这张图显然是O(N^2)可以做的 然后其实就比较简单了 首先为了满足独立集,我们需要保证所取元素递增 为了满足覆盖集,我 ...

  5. 【NOI模拟赛】黑色大桥(DP优化,李超树)

    题面 时间限制:1s,空间限制:1024MB 题目描述 手拿咒刃砍金门,众神直呼不是人 椅子玩自定义咒刃,一路打到了第三关的银行,祂想在黑色大桥无伤看守者之前找点刺激的. 加了模组的银行极大.具体地说 ...

  6. 【模拟赛】沼泽地(插头DP)

    背景 (创作声明:包含虚构创作) 自从阴暗潮湿的沼泽地里莫名其妙生长出红树的那一刻起,有一种传说中的红皮肤怪物诞生了. 它们在沼泽莲叶上发出诱人的声响,它们身形小巧,穿梭于水草和藤蔓之间. 第一天便有 ...

  7. YbtOJ#20235-[冲刺NOIP2020模拟赛Day9]公共序列【dp】

    正题 题目链接:https://www.ybtoj.com.cn/contest/66/problem/3 题目大意 给出两个字符串A,BA,BA,B,求它们的最长公共子序列. 解题思路 先考虑朴素的 ...

  8. 【2018.4.14】模拟赛之四-ssl2394 剪草【dp】

    正题 大意 有n株草,没个时间单位开始时会增长不同的长度.每个时间单位可以将一株草剪成高度为0,求多少时间单位后能够将草的总高度减低为h以下,或用远不能. 解题思路 首先需要一段玄学推理: 可以等草长 ...

  9. 【2018.4.7】模拟赛之五-ssl2386 序列【dp】

    正题 大意 好序列的定义为每一个数是前面一个数的倍数.求1到n里长度为k的好序列的个数 解题思路 f[i][j]f[i][j]f[i][j]表示第i位数为j的最优解,然后动态转移方程 f[i+1][j ...

最新文章

  1. Ocelot + Consul实践
  2. The Elements of Statistical Learning的笔记
  3. PyQt5 技术篇-调用颜色对话框(QColorDialog)获取颜色,调色板的调用。
  4. oracle 查看 用户,用户权限,用户表空间,用户默认表空间
  5. Mozilla的Python3使用情况
  6. python基于web可视化_Python Selenium实现无可视化界面
  7. C#中PostMessage和SendMessage的参数传递实例
  8. 大话重构连载9:大布局你伤不起
  9. LightOJ - 1282 Leading and Trailing
  10. Python 库 PyPI 危机!
  11. php无缝滚动文字,使用JS如何实现文字无缝滚动
  12. ora03113通信通道的文件结尾 会话id 149 序列号 3
  13. [JPA错误]javax.persistence.EntityNotFoundException: Unable to find xxx
  14. 【案例】Python金融分析-CAPM模型对股票进行分析
  15. PointNet论文翻译
  16. 对php课程的建议,万紫千红总是春——对新课程语文教学、复习的建议与采饶措施a href=http://www.ruiwen.com/friend/list.php(教师中心专稿)/a...
  17. 按照从右向左的阅读顺序,返回一个不含重复数字的新的整数
  18. 服务器虚拟化vmware hyper-v,浅谈Hyper-v与VMware服务器虚拟化比较
  19. 运筹学研究者关注的Github和CSDN账号
  20. 华为无线wifi无服务器,华为wifi设置后设备无法上网该怎么解决 | tplogin.cn

热门文章

  1. 尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。
  2. numpy_arrange函数
  3. 利用Python爬虫网上的漂亮妹子图
  4. Vue cli3配置生产环境,开发环境,和测试环境
  5. python时间戳转日期字符串
  6. 《炬丰科技-半导体工艺》不同电解质对多孔氮化镓的影响
  7. 关于MCU中Timer/Counter接口及使用
  8. 如何使用Hexo搭建属于自己的博客
  9. 使用 iReport中table组件制作表格导出PDF
  10. Entry name ‘AndroidManifest.xml‘ collided