4-4模拟赛 囚人的旋律——DP

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

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

start_of_题面

【问题描述】

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

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

这里写图片描述

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

接下来的问题就和监狱游戏没有太多关系了。我们令 a [ i ] a[i] a[i]表示看守的第i扇门对应囚犯的哪一扇门。令图G为有n个节点的图,编号为 1 ∼ n 1 ∼ n 1n。对于满足 1 ≤ i &lt; j ≤ n 1 ≤ i &lt;j ≤ n 1i<jn一对 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 SV是一个独立集当且仅当对于任意两个点 u , v ∈ V u, v ∈ V u,vV,不存在 u , v ∈ E u, v ∈ E u,vE。而 S S S是一个覆盖集当且仅当对于任意点 v ∉ S v ∉ S v/S存在点 u ∈ S u ∈ S uS满足 u , v ∈ E u, v ∈ E u,vE

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

【输入格式】

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

【输出格式】

输出一个整数,表示方案数对 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 n20
对于 60%的数据, n ≤ 100 n ≤ 100 n100
对于 100%的数据, n ≤ 1000 n ≤ 1000 n1000 0 ≤ m ≤ n ( n − 1 ) 2 0 ≤ m ≤ \frac{n(n-1)}{2} 0m2n(n1)

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<ja[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 long

const 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有这样一类成功者:他们经商致富,于居室外置庭院,院中有亭翼然,亭上挂一面额。此时倘有人将“醉翁亭”题至编额中。主人公拍手称快道:“妙哉!”而若将“饮酒亭”题至匾额中,主人则不假思索道:“俗哉!”此类人追求文人本题。但实际上胸无点墨,只管把自己强行嵌入“雅”的框架中,就如同大观园中只顾赏花却不懂花的“伪君子”,总不免贻笑大方。 自古以来,世上总有各种困在框架里而不自知的人。他们如流水般虚浮,惯于遵从过去的经验或偏听一家之言,拘泥于既定枢架范式中。这些框架如同牢笼,让人的思维日渐固化,仿佛被“囚”于牢笼中,不见天日。归根结底,还是人本身缺乏硬实力所致。 在崇尚理学的明清时期,几乎所有人都成了封建社会值硬刻板的“木偶人”。可曹雪芹却通过笔下两个鲜明的角色,跳出了框架的束缚。此二人便是贾宝玉和林黛玉。他们不仅才华横溢,也在教育的熏陶中造就了自己独特的思维方式。这是一种因时因地制宜而去伪存真、去粗取精的思维方法,这样的方法可以教会一个人不要只顾跟随领跑者,而要学会超越领跑者,我愿称之为“宝黛思维”。 春秋时期的美女西施,天生丽质,举手投足间都流露着妩媚与柔情,而那些仰慕西施不顾现实加以效仿的人,不仅失去自己的特点,还闹出东施效颦的笑话。在全民创造短视频的热潮中,李子柒结合自己的兴趣与特长,对中国传统文化加以创新,以最具时代特征的形式,推动中国文化走向世界。由此可见,我们为人处世应当学习“宝黛思维”,以因地制宜为前提,实破框架束缚,勇于创新,方能成事。 虽说“他山之石,可以攻玉”。但真正的好玉,还得用心细“攻”,而非“一锤定音”,强行为之套上框架。只有培养并运用“宝黛思维”,才不会在山清水秀时自我陶醉而落入俗套,才不会在山穷水尽时野驴技穷而止步不前。只有跳出框架的人,才能知所进,知所惧,知所适。识时务。 “宝黛思维”可激发人的潜力,帮助我们脱去少年的程格。少年的我们唯有善用“宝黛思维”,方可跳出“囚人”的框架,释放知识和人生的光彩。 总结大意
02-17

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值