CodeForces5E 环转链,dp思想
http://codeforces.com/problemset/problem/5/E
众所周知,在很久以前,在今天的 Berland 地区,居住着 Bindian 部落。他们的首都被 n 座山所环绕,形成了一个圆形。在每座山上,有一名看守人,昼夜看守着相邻的山。 万一出现了任何危险,看守人可以在山上点燃烽火。如果连接两座山的圆弧上,没有任何山高于这两座山中的任何一座,那么这两座山的一个看守人可以看见另一个看守人的信号。对于任意两座山,由于存在两条不同的圆弧连接着它们,如果在至少一条圆弧上满足前述条件,信号就能被看见。例如,对于任意两个相邻的看守人,一方的信号将能够被另一方看见。 这个守护系统的一个重要特性,就是能够相互看见对方信号的看守人“成对”的数目。请根据给定各山的高度,求出这样的“成对”数目。 输入
输入数据的第一行,包含了一个整数 n ( ≤ n ≤ ), n — 环绕首都的山的数量。第二行包含了 n 个数字 — 按顺时针顺序的各山的高度。所有的高度数字为整数,介于 到 之间。 输出
打印所要求的“成对”数目。
题意
首先遇到的就是对环的操作,很显然直接在环上操作是不那么容易的,开始想到对整个链进行延长两倍的操作进行处理,但是这样会很麻烦,难以下手
由于这题的特殊特性,当我们尝试把最高的山脉放在链的最左边时,整个环就变成了一个相同题意下的链,可以方便操作很多。
一个小技巧在寻找最大值的时候用一个变量存储最大值下标可以很便捷
然后遇到的问题就是求对数,开始想到了单调队列去做,但是因为会有类似 1 1 2 2这样的样例,单调队列很难维护
只能考虑用其他的方法
我们假设每一个山脉都是对数里面较低的山脉,我们对每个山脉计算的就只有两边比他大的山脉。
由此得到维护一个left数组,right数组表示这个山脉两边比他高的山脉,如果存在就ans++
但是还有一个问题就是1 1 1 1 这个样例,所有等高山脉是可以互相看见的。我们还需要计算l 到 r 之间和这个山脉高度相等的山脉加上去。
加两边会导致重复计算,如果每一个山脉都只加右边,就可以完美规避这个问题,也就是说用一个same数组来存储这个i 到 right[i]之间有多少和他高度相同的山脉
求left right same的方法当然不是暴力,用dp的思想可以在线性的时间内解决这个问题
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double eps = 1e-;
const int maxn = 1e6 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,tmp,K;
int a[maxn];
int b[maxn];
int Left[maxn],Right[maxn],same[maxn];
int main()
{
Sca(N);
For(i,,N) Sca(a[i]);
int MAX = ;
For(i,,N){
if(a[i] > a[MAX]) MAX = i;
}
For(i,,MAX - ){
b[N - MAX + + i] = a[i];
}
For(i,MAX,N){
b[i - MAX + ] = a[i];
}
int cnt = ;
Left[] = ;
For(i,,N){
Left[i] = i - ;
while(Left[i] > && b[Left[i]] <= b[i]){
Left[i] = Left[Left[i]];
}
}
_For(i,N,){
Right[i] = i + ;
while(Right[i] <= N && b[Right[i]] < b[i]){
Right[i] = Right[Right[i]];
}
if(Right[i] <= N && b[Right[i]] == b[i]){
same[i] = same[Right[i]] + ;
Right[i] = Right[Right[i]];
}
}
LL ans = ;
For(i,,N){
ans += same[i] + ;
if(Left[i] == && Right[i] == N + ){
ans--;
}
}
Prl(ans);
#ifdef VSCode
system("pause");
#endif
return ;
}
CodeForces5E 环转链,dp思想的更多相关文章
- P1880 [NOI1995]石子合并 区间dp+拆环成链
思路 :一道经典的区间dp 唯一不同的时候 终点和起点相连 所以要拆环成链 只需要把1-n的数组在n+1-2*n复制一遍就行了 #include<bits/stdc++.h> usi ...
- 【BZOJ-2937】建造酿酒厂 前缀和 + 展环为链 + 乱搞
2937: [Poi2000]建造酿酒厂 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 70 Solved: 24[Submit][Status][D ...
- 到底什么是dp思想(内含大量经典例题,附带详细解析)
期末了,通过写博客的方式复习一下dp,把自己理解的dp思想通过样例全部说出来 说说我所理解的dp思想 dp一般用于解决多阶段决策问题,即每个阶段都要做一个决策,全部的决策是一个决策序列,要你求一个 最 ...
- hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)
Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- DP思想在斐波那契数列递归求解中的应用
斐波那契数列:1, 1, 2, 3, 5, 8, 13,...,即 f(n) = f(n-1) + f(n-2). 求第n个数的值. 方法一:迭代 public static int iterativ ...
- hdu 4612 Warm up 双连通+树形dp思想
Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total S ...
- DAG上dp思想
DAG上DP的思想 在下最近刷了几道DAG图上dp的题目.要提到的第一道是NOIP原题<最优贸易>.这是一个缩点后带点权的DAG上dp,它同时规定了起点和终点.第二道是洛谷上的NOI导刊题 ...
- 湖南省第十二届大学生计算机程序设计竞赛 B 有向无环图 拓扑DP
1804: 有向无环图 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 187 Solved: 80[Submit][Status][Web Board ...
- 图论 公约数 找环和链 BZOJ [NOI2008 假面舞会]
BZOJ 1064: [Noi2008]假面舞会 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1655 Solved: 798[Submit][S ...
随机推荐
- Fourier Transform Complex Conjugate Discussion
FT of function $f(t)$ is to take integration of the product of $f(t)$ and $e^{-j\Omega t}$. By separ ...
- 1、linux下对绝对路径和相对路径
cd / 回到根目录 cd /etc 回到根目录下的etc 目录下 绝对路径 路径写法是从根目录/ 写起来的. cd . 当前目录 cd .. 上层目录 cd ~回到自家的根目 ...
- NFS共享存储的使用
概述 NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布.功能是通过网络让不同的机器.不同的操作系统能够彼此 ...
- docker--Dockerfile-nginx
# 基础镜像 FROM alpine # 作者信息 MAINTAINER NGINX Docker Maintainers "1024331014@qq.com" # 修改源 RU ...
- #189 stat(动态规划)
容易想到固定第一个排列为1~n,算出答案后乘上n!即可,但这样就离正解走远了. 考虑排列dp的一般套路,将数从大到小加入排列,这样每个位置第一次填数时(不管是第一个还是第二个排列)其贡献就确定了. 显 ...
- Elasticsearch 分片路由原理指定分片存储查询
Elasticsearch 项目中使用到Es的父子结构.在数据填充之后,查看每个节点的数据分布情况,发现有的节点数据多,有的节点少的情况,在未使用Es父级结构之前,每个节点的数据分布还算平均,如下图: ...
- 洛谷3707 [SDOI2017] 相关分析 【线段树】
分析: 化简一下就行了,注意一下平方和公式的运用以及精度的误差. 代码: #include<bits/stdc++.h> using namespace std; ; int n,m; i ...
- 【XSY2759】coin DP 线性插值
题目描述 有\(n\)种面值不同的硬币,每种有无限个,且任意两个\((x,y)\)要么\(x\)是\(y\)的倍数,要么\(y\)是\(x\)的倍数. 你要取\(m\)元钱,问你有多少种不同的取法. ...
- 华为TaiShan 2280 ARM 服务器
华为TaiShan 2280 ARM 服务器 华为TaiShan 2280 ARM 服务器 https://e.huawei.com/cn/products/cloud-computing-dc/s ...
- 【比赛】NOIP2018 货币系统
可以发现最后的集合一定是给定集合的子集 所以就变成了裸的背包嘛,对于每个数判断它能不能被其它数表示出来,如果可以,就表示这个数是没用的,可以去掉 #include<bits/stdc++.h&g ...