[CSP-S模拟测试]:折射(DP)

Posted wzc521

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CSP-S模拟测试]:折射(DP)相关的知识,希望对你有一定的参考价值。

题目描述

  小$Y$十分喜爱光学相关的问题,一天他正在研究折射。
  他在平面上放置了$n$个折射装置,希望利用这些装置画出美丽的折线。
  折线将从某个装置出发,并且在经过一处装置时可以转向,若经过的装置坐标依次为$(x_1,y_1),(x_2,y_2),...(x_k,y_k)$,则必须满足:
  $\\bullet \\forall j\\in (1,k],y_j<y_j−1$
  $\\bullet \\forall j\\in (2,k],x_j−2<x_j<x_j−1or\\ x_j−1<x_j<x_j−2$
  现在他希望你能告诉他,一共有多少种不同的光线能被他画出来,两种光线不同当且仅当经过的折射装置的集合不同。你只需要告诉他答案对$10^9+7$取模后的结果。


输入格式

第一行一个正整数$n$,表示折射装置的数量。
接下来$n$行,每行两个整数$x_i,y_i$表示折射装置的坐标。


输出格式

输出一行一个整数,表示答案对$10^9+7$取模后的结果。


样例

样例输入:

4
2 2
3 1
1 4
4 3

样例输出:

14


数据范围与提示

对于$10\\%$的数据:$n\\leqslant 700,1\\leqslant x_i,y_i\\leqslant N$
对于$20\\%$的数据:$n\\leqslant 1,000,1\\leqslant x_i,y_i\\leqslant N$
对于$50\\%$的数据:$n\\leqslant 4,000,|x_i|,|y_i|\\leqslant 10^9$
对于$100\\%$的数据:$n\\leqslant 6,000,|x_i|,|y_i|\\leqslant 10^9$
所有数据满足$\\forall i\\neq j,x_i\\neq x_j\\ and\\ y_i\\neq y_j$。


题解

考试的时候上去就将$y_i$排了个序,然后我就死了……

这道题就是让你找形如下图的图形有多少个:

技术图片

因为给$y_i$排序不好处理,所以我们考虑给$x_i$排序。

那么我们考虑$DP$,设$dp[i][0/1]$表示第$i$个点为顶端,向左或向右的方案数。

那么我们可以列出状态转移方程:

  $\\alpha.\\forall y_j<y_i,dp[i][0]\\leftarrow dp[j][1]$。

  $\\beta.\\forall y_j>y_i,dp[j][1]\\leftarrow dp[k][0]|x_k>x_j\\ and\\ y_k<y_i$。

时间复杂度:$\\Theta(n^2)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n;
pair<int,int> p[6001];
int dp[2][6001];
int main()

	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d%d",&p[i].first,&p[i].second);
	sort(p+1,p+n+1);
	for(int i=1;i<=n;i++)
	
		dp[0][i]=dp[1][i]=1;
		for(int j=i-1;j;j--)
			p[i].second>p[j].second?dp[0][i]=(dp[0][i]+dp[1][j])%1000000007:dp[1][j]=(dp[1][j]+dp[0][i])%1000000007;
	
	for(int i=1;i<=n;i++)dp[0][0]=(dp[0][0]+(dp[0][i]+dp[1][i])%1000000007)%1000000007;
	printf("%d",(dp[0][0]-n+1000000007)%1000000007);
	return 0;


rp++

以上是关于[CSP-S模拟测试]:折射(DP)的主要内容,如果未能解决你的问题,请参考以下文章

[CSP-S模拟测试]:花(DP)

csp-s模拟测试92

[CSP-S模拟测试]:蛇(DP+构造+哈希)

[CSP-S模拟测试]:F(DP+线段树)

[CSP-S模拟测试]:题(DP)

[CSP-S模拟测试]:优化(贪心+DP)