博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Problem 4 dp
阅读量:4609 次
发布时间:2019-06-09

本文共 1532 字,大约阅读时间需要 5 分钟。

$des$

小 $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 - 1} 或者 x_{j - 1} < x_j < x_{j - 2}$
求不同种的画法

$sol$

按 $x$ 坐标排序,$f_{i, 0/1}$ 表示以第 $i$ 个点为顶端下来向左或向右的折线的方案数

从左到右加点,考虑前 $i$ 个点构成的包含 $i$ 点的折线,由于新点横坐标最大, 所以只可能在折线的
第一位或第二位:
1. $\forall y_j < y_i, f_{i, 0} \gets f_{j, 1}$
2. $\forall y_j > y_i, f_{j, 1} \gets f_{k, 0} | x_k > x_j 且 y_k < y_i$
第二种情况可以前缀和优化, 复杂度 $O(n^2)$

$code$

#include 
using std::pair;typedef long long ll;typedef pair
pii;#define fst first#define snd secondconst int oo = 0x3f3f3f3f;#define gc getchar()inline int read() { int x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;}const int N = 6000;const int mo = 1e9 + 7;pii p[N + 5];int dp[N + 5][2], n;int main() { n = read(); for(int i = 1; i <= n; i++) p[i].fst = read(), p[i].snd = read(); sort(p + 1, p + n + 1); for(int i = 1; i <= n; i++) { dp[i][0] = dp[i][1] = 1; for(int j = i - 1; j >= 1; j--) if(p[j].snd > p[i].snd) (dp[j][1] += dp[i][0]) %= mo; else (dp[i][0] += dp[j][1]) %= mo; } int ans = mo - n; for(int i = 1; i <= n; i++) ans = ((ans + dp[i][0]) % mo + dp[i][1]) % mo; std:: cout << ans; return 0;}

 

转载于:https://www.cnblogs.com/shandongs1/p/9768845.html

你可能感兴趣的文章
POJ 2386 Lake Counting
查看>>
position
查看>>
Oracle 修改现有列的数据类型
查看>>
存储过程、插入数据后直接过去主键id
查看>>
系统的程序有问题怎么办
查看>>
服务器与多个客户端通信
查看>>
从北京回来的年轻人,我该告诉你点什么?
查看>>
关于bootstrap中行格式化
查看>>
C#利用NPOI导出Excel
查看>>
jFinal基于maven简单的demo
查看>>
cocos2d学习笔记
查看>>
Redis 四:存储类型之无序集合
查看>>
[CQOI2016]K远点对
查看>>
后缀自动机入门题集
查看>>
小练习:计算汉明距离
查看>>
javascript动态创建表格:新增、删除行和列
查看>>
C# VS 2010创建、安装、调试 windows服务(windows service)
查看>>
php aes128加密
查看>>
o怎么样racle输入dmp数据库文件
查看>>
Linux------创建和终止进程
查看>>