2018雅礼集训 DAY1T2 折射

自闭了,题解都看不懂。

Desprition

小 Y 十分喜爱光学相关的问题, 一天他正在研究折射. 他在平面上放置了 (n) 个折射装置, 希望利用这些装置画出美丽的折线

折线将从某个装置出发, 并且在经过一处装置时可以转向, 若经过的装置坐标依次为 ((x1, y1),(x2, y2)) . . .((xk, yk)),

则必须满足:

(∀) $j in (1, k], y_{j-1} < y_j $

(∀) (j in (2 ,k]), (x_{j- 2} < x_j < x_{j_1}) (or) $ x_{j-1} < x_j < x_{j-2}$

现在他希望你能告诉他, 一共有多少种不同的光线能被他画出来, 两种光线不同当且仅当经过的折射装置的集合不同

. 你只需要告诉他答案对 (10^9 +7) 取模后的结果

.Input Format

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

Output Format

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

.Constraints

对于 10% 的数据: (n≤ 700, 1 ≤ x_i, y_i≤N)

对于 20% 的数据: (n≤ 1000, 1 ≤x_i, y_i≤N)

对于 50% 的数据: (n≤ 4000,|x_i|,|y_i | ≤ 10^9)

对于 100% 的数据: (n ≤ 6000,|x_i|,|y_i| ≤ 10^9)

sloution

自闭了,考试的时候连 (O(n^2)) 的暴力都不会,直接粘题解吧

(dp[i][0/1]) 表示按 (x) 排序,以 (i) 为入射点的光线,向左下方 0/右下方1入射,注意这里前 (i) 并不是状态,因为

后面可以更改这个 (dp_i) 状态。按 (x) 排序只是方便处理。

转移:

(∀) (y_j < y_i, dp[i][0] <- dp[j][1])

(∀) (y_j > y_i) ,(dp[j][1] <- dp[k][0]) (y_k < y_j and x_k > x_j)

搬运完成

不知道为什么把 (f[i][0],f[i][1]) 初始化放在外面就不对。

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 6010;
const int p = 1e9+7;
int n,ans,f[N][2];
struct node
{
	int x,y;
}e[N];
inline int read()
{
    int s = 0,w = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
    return s * w;
}
bool cmp(node a,node b)
{
	return a.x < b.x;
}
int main()
{
	freopen("refract.in","r",stdin);
	freopen("refract.out","w",stdout);
    n = read();
    for(int i = 1; i <= n; i++)
    {
        e[i].x = read();
        e[i].y = read();
    }
    sort(e+1,e+n+1,cmp);
    f[1][0] = f[1][1] = 1;
    for(int i = 2; i <= n; i++)
    {
    	f[i][0] = f[i][1] = 1;
        for(int j = i-1; j; j--)
        {
            if(e[j].y > e[i].y) f[j][1] += f[i][0], f[j][1] %= p;
            if(e[j].y < e[i].y) f[i][0] += f[j][1], f[i][0] %= p;
        }
    }
    for(int i = 1; i <= n; i++) ans = (1LL * ans + f[i][0] + f[i][1]) % p;
    printf("%d
",(ans - n + p) % p);
    fclose(stdin); fclose(stdout);
    return 0;
}
原文地址:https://www.cnblogs.com/genshy/p/13877214.html