FZU1862(线段树 或者 DP)
Accept: 100 Submit: 249
Time Limit: 2000 mSec Memory Limit : 32768 KB
Problem Description
are N numbers (non-negative integers) in a circle. Now your task is
quite simple, just tell me the largest number between L and R.
The Figure 1 is a sample of five integers in a circle. (marked with their index, but not their exact value.)
Figure 1.
The Figure 2,3 show how we count the number.
Figure 2.
Figure 3.
Input
There are no more than 10 test cases;
For each case, the first line contains only one integer N, indicates the size of the circle.
The following one line contains N non-negative integers where Mi
indicates the i-th integers whose index is i. (1 <= N <= 1000, 1
<= i <= N, 0 <= Mi <= 10^9)
Then one line contains Q indicates the number of querys. (1 <= Q <= 10^5)
Then the next Q lines, each line contains only two integers indicate L and R (1 <= L,R <= N)
Output
For each case, please output “Case #index:” in a single line, here index is the case index starts from one.
For each query just output a single line indicates the largest number between L and R.
Output a blank line after each case.
Sample Input
3 8
3
1 1
1 2
2 1
1
9
1
1 1
Sample Output
3
8
8
Case #2:
9
Hint
Huge Input, please “scanf” to avoid time limit exceed.
题意:在给定的区间中查询最大的数。当L>R时,R =R +n 来改变R这也是2*n的原因;
方法1:线段树
收获:函数中的num指的是线段树上的编号,而当le == ri时,le 或 ri指的是最低层的编号。
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
using namespace std; const int INF=0x3f3f3f3f;
const double eps=1e-;
const double PI=acos(-1.0);
#define maxn 8006
int tre[maxn];
int a[maxn/];
int n;
void build(int num, int le, int ri)
{
if(le == ri)
{
if(le > n)
tre[num] = a[le-n];//函数中的num指的是线段树上的编号,而当le == ri时,le 或 ri指的是最低层的编号。
else
tre[num] = a[le];
return;
}
int mid = (le + ri)/;
build(num*, le, mid);
build(num*+, mid+, ri);
tre[num] = max(tre[num*], tre[num*+]);
}
int query(int num,int le,int ri,int x,int y)
{
if(x<=le&&y>=ri)
return tre[num];
int mid=(le+ri)/;
int ans=;
if(x<=mid)
ans=max(ans,query(num*,le,mid,x,y)); //先查询左边
if(y>mid)
ans=max(ans,query(num*+,mid+,ri,x,y)); //再查询右边
return ans;
}
int main()
{
int cas = ;
while(~scanf("%d", &n))
{
for(int i = ; i <= n; i++)
scanf("%d", &a[i]);
build(, , *n);
int m;
scanf("%d", &m);
int a, b;
printf("Case #%d:\n", cas++);
for(int j = ; j < m; j++)
{
scanf("%d%d", &a, &b);
if(b < a)
b = b + n;
printf("%d\n", query(, , *n, a, b));
}
puts("");
}
}
方法2:DP
收获:对dp有了更多的了解。
dp[i][j]指的是i到j这个区间内保存的最大值。
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
#define C 0.57721566490153286060651209
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 using namespace std; typedef long long LL;
const int INF=0x3f3f3f3f;
const double eps=1e-;
const double PI=acos(-1.0); const int maxn=;
int dp[][];
int a[];
int main()
{
int n, b;
int sum=;
while(~scanf("%d", &n))
{
for(int i = ; i <= n; i++)
{
scanf("%d", &b);
a[i]=a[i+n]=b;
}
for(int i = ; i <=*n; i++)
{
dp[i][i]=a[i];
for(int j=i+;j<=*n;j++)
{
if(a[j]>dp[i][j-])
dp[i][j]=a[j];
else
dp[i][j]=dp[i][j-];
}
}
int m;
scanf("%d", &m);
int L, R;
printf("Case #%d:\n",++sum);
for(int i=;i<=m;i++)
{
int q,w;
scanf("%d%d",&q,&w);
if(w<q)
w=w+n;
printf("%d\n",dp[q][w]);
}
puts("");
}
return ;
}
FZU1862(线段树 或者 DP)的更多相关文章
- Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)
题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...
- 2018.09.12 poj2376Cleaning Shifts(线段树+简单dp)
传送门 貌似贪心能过啊%%%. 本蒟蒻写的线段树优化dp. 式子很好推啊. f[i]表示覆盖1~i所需的最小代价. 那么显然对于一个区间[li,ri]" role="present ...
- 2018.07.08 hdu4521 小明系列问题——小明序列(线段树+简单dp)
小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Proble ...
- CF833B The Bakery 线段树,DP
CF833B The Bakery LG传送门 线段树优化DP. 其实这是很久以前就应该做了的一道题,由于颓废一直咕在那里,其实还是挺不错的一道题. 先考虑\(O(n^2k)\)做法:设\(f[i][ ...
- Codeforces Round #426 (Div. 2) D 线段树优化dp
D. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
- BZOJ2090: [Poi2010]Monotonicity 2【线段树优化DP】
BZOJ2090: [Poi2010]Monotonicity 2[线段树优化DP] Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. ...
- Codeforces 834D The Bakery 【线段树优化DP】*
Codeforces 834D The Bakery LINK 题目大意是给你一个长度为n的序列分成k段,每一段的贡献是这一段中不同的数的个数,求最大贡献 是第一次做线段树维护DP值的题 感觉还可以, ...
- [AGC011F] Train Service Planning [线段树优化dp+思维]
思路 模意义 这题真tm有意思 我上下楼梯了半天做出来的qwq 首先,考虑到每K分钟有一辆车,那么可以把所有的操作都放到模$K$意义下进行 这时,我们只需要考虑两边的两辆车就好了. 定义一些称呼: 上 ...
随机推荐
- 【剑指offer】面试题27:二叉搜索树与双向链表
题目: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路: 假设已经处理了一部分(转换了左子树),则得到一个有序的双向链表,现在 ...
- nodejs学习笔记之包、模块实现
简单了解了node的安装和一些基本的常识之后,今天学习了node中很重要的包和模块的一些知识点. 首先学习一下包的规范,它由包结构和包描述两部分组成.包结构用于组织包的各种文件,包 ...
- Javascript 中的变量
var a; console.log("The value of a is " + a); // The value of a is undefined console.log(& ...
- matlab学习
1.将一个图片嵌入一张图里,去除黑边 clc clear close all I = imread('qiegray.jpg'); I = rgb2gray(I); I = double(I); I1 ...
- UIKit和Core Graphics绘图(三)——绘制虚线,椭圆以及饼图
绘制虚线 虚线绘制主要调用CGContextSetLineDash函数. 这个函数有4个参数,除了一个是上下文外,phase为初始跳过几个点开始绘制,第三个参数为一个CGFloat数组,指定你绘制的样 ...
- Qt相关问题
1. Qt编译中的error: cannot find -lGL和 error: collect2: error: ld returned 1 exit status 一般见于新安装的系统,马上就直 ...
- MVC Razor 一些常用的方法
一.在ASP.NET MVC中,创建视图最典型的方式是调用一个action方法,它使用模型准备视图数据.action方法然后调用控制器的视图方法创建视图. 1 <% Html.RenderAct ...
- Mysql 复制表结构 及其表的内容
顺便转一下Mysql复制表结构.表数据的方法: 1.复制表结构及数据到新表CREATE TABLE 新表 SELECT * FROM 旧表 这种方法会将oldtable中所有的内容都拷贝过来,当然我们 ...
- js静态方法
1.ajax() 方法是属于“函数”本身的,和返回的对象没有关系 2.bark药调用,必须药new Hashiqi()得到对象,且由返回对象才能调用 3.ajax()方法药调用,不需要new对象,直接 ...
- 某Java游戏服务器用到的知识
Runtime.getRuntime().addShutdownHook(shutdownHook); shutdownHook()函数可以在jvm关闭的时候进行内存清理.对象销毁等操作 http:/ ...