Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >洛谷P4563 [JXOI2018]守卫(dp)

洛谷P4563 [JXOI2018]守卫(dp)

作者头像
attack
发布于 2019-03-11 02:30:08
发布于 2019-03-11 02:30:08
45200
代码可运行
举报
运行总次数:0
代码可运行

题意

题目链接

Sol

非常有意思的题目。

我们设\(f[l][r]\)表示区间\([l,r]\)的答案。

显然\(r\)位置一定有一个保镖

同时不难观察到一个性质:拿\([1, n]\)来说,设其观察不到的某个区间为\([l_k, r_k]\),那么\(r_k\)与\(r_k + 1\)一定有一个保镖,而且每段区间的贡献都是独立的。

这样我们可以预处理出任意两个点是否能看见(直接记上一个能看到的位置然后比较斜率)。

然后直接枚举\(r\),不断把\(l\)往左移动更新答案,这样可以保证更新的时候中间的区间都计算过,可以直接前缀和优化

复杂度\(O(n^2)\)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<bits/stdc++.h>
#define Fin(x) freopen(#x".in", "r", stdin);
using namespace std;
const int MAXN = 5001;
template<typename A, typename B> inline bool chmax(A &x, B y) {return x < y ? x = y, 1 : 0;}
template<typename A, typename B> inline bool chmin(A &x, B y) {return x > y ? x = y, 1 : 0;}
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, f[MAXN][MAXN];
double a[MAXN];
bool can[MAXN][MAXN];
int main() {
    //Fin(a);
    N = read();
    for(int i = 1; i <= N; i++) a[i] = read();
    for(int i = 1; i <= N; i++) {
        for(int j = i - 1, las = -1; j; j--) 
            if((las == -1) || (1ll * (a[i] - a[las]) * (i - j) > 1ll * (a[i] - a[j]) * (i - las))) 
                can[i][j] = can[j][i] =1, las = j;
    }
    int ans= 0;
    for(int i = 1; i <= N; i++) {
        int s = 1, las = 0;
        for(int j = i; j; j--) {
            if(can[j][i]) {
                if(!can[j + 1][i]) s += min(f[j + 1][las], f[j + 1][las + 1]);
                f[j][i] = s;
            } else {
                if(can[j + 1][i]) las = j;
                f[j][i] = s + min(f[j][las], f[j][las + 1]);
            }
            ans ^= f[j][i];
        //  printf("%d ", f[j][i]);
        }
    //  puts("");
    }
    cout << ans;
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-02-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
洛谷P4063 [JXOI2017]数列(dp)
这题想还是不难想的,就是写起来很麻烦,然后去看了一下loj的最短代码表示只能Orz
attack
2019/03/11
3870
洛谷P4562 [JXOI2018]游戏(组合数学)
因此总的方案为\(\sum_{i=cnt}^{r-l+1} C_{i-1}^{cnt-1} cnt! (r - l + 1 - cnt)!\)
attack
2019/03/11
5120
洛谷P4561 [JXOI2018]排序问题(二分 期望)
一次排好的概率是个数数题,他等于一次排好的方案除以总方案,也就是\(\frac{\prod cnt_{a_i}!}{(n+m)!}\)。因为最终的序列是一定的,两个序列不同当且仅当权值相同的数排列方式不同。
attack
2019/03/11
3900
洛谷P4425 [HNOI/AHOI2018]转盘(线段树)
首先猜一个结论:对于每次询问,枚举一个起点然后不断等到某个点出现时才走到下一个点一定是最优的。
attack
2019/03/06
4320
洛谷P4462 [CQOI2018]异或序列(莫队)
题意 题目链接 Sol 一开始以为K每次都是给出的想了半天不会做。 然而发现读错题了维护个前缀异或和然后直接莫队搞就行,。 #include<bits/stdc++.h> #define Pair pair<int, int> #define MP(x, y) make_pair(x, y) #define fi first #define se second //#define int long long #define LL long long #define Fin(x) {freopen(#x
attack
2019/03/15
3350
洛谷P4170 [CQOI2007]涂色(区间dp)
裸的区间dp,\(f[l][r]\)表示干掉\([l, r]\)的最小花费,昨天写的时候比较困于是就把能想到的转移都写了。。
attack
2019/03/15
4560
洛谷P2868 [USACO07DEC]观光奶牛Sightseeing Cows(01分数规划)
设\(a_i\)为点权,\(b_i\)为边权,我们要最大化\(\sum \frac{a_i}{b_i}\)。可以二分一个答案\(k\),我们需要检查\(\sum \frac{a_i}{b_i} \geqslant k\)是否合法,移向之后变为\(\sum_{a_i} - k\sum_{b_i} \geqslant 0\)。把\(k * b_i\)加在出发点的点权上检查一下有没有负环就行了
attack
2019/03/15
3690
loj#2049. 「HNOI2016」网络(set 树剖 暴力)
因为从一个点向上只会跳\(logn\)次,所以可以暴力的把未经过的处理出来然后每个点开个multiset维护最大值
attack
2019/03/15
3770
洛谷P3199 [HNOI2009]最小圈(01分数规划)
题意 题目链接 Sol 暴力01分数规划可过 标算应该是这个 #include<bits/stdc++.h> #define Pair pair<int, double> #define MP(x, y) make_pair(x, y) #define fi first #define se second //#define int long long #define LL long long #define Fin(x) {freopen(#x".in","r",stdin);} #define F
attack
2019/03/15
4130
洛谷P3586 [POI2015]LOG(贪心 权值线段树)
题意 题目链接 Sol 显然整个序列的形态对询问没什么影响 设权值\(>=s\)的有\(k\)个。 我们可以让这些数每次都被选择 那么剩下的数,假设值为\(a_i\)次,则可以\(a_i\)次被选择 一个显然的思路是每次选最大的C个 那么只需要判断\(\sum a_i >=(c - k)*s\)即可 权值线段树维护一下 #include<bits/stdc++.h> #define Pair pair<int, int> #define MP(x, y) make_pair(x, y) #define f
attack
2019/03/05
5640
loj#6074. 「2017 山东一轮集训 Day6」子序列(矩阵乘法 dp)
然后发现可以用矩阵优化,可以分别求出前缀积和逆矩阵的前缀积(这题的逆矩阵炒鸡好求)
attack
2019/04/01
5350
洛谷P2973 [USACO10HOL]赶小猪(高斯消元 期望)
设\(f[i]\)表示炸弹到达\(i\)这个点的概率,转移的时候考虑从哪个点转移而来
attack
2019/01/30
4100
BZOJ1802: [Ahoi2009]checker(性质分析 dp)
题意 题目链接 Sol 一个不太容易发现但是又很显然的性质: 如果有两个相邻的红格子,那么第一问答案为0, 第二问可以推 否则第一问答案为偶数格子上的白格子数,第二问答案为偶数格子上的红格子数 #include<bits/stdc++.h> #define Pair pair<int, int> #define MP(x, y) make_pair(x, y) #define fi first #define se second //#define int long long #define LL lo
attack
2019/02/26
3650
洛谷P4104 [HEOI2014]平衡(dp 组合数学)
可以把题目转化为从\([1, 2n + 1]\)中选\(k\)个数,使其和为\((n+1)k\)。
attack
2019/03/11
2830
loj#6041. 「雅礼集训 2017 Day7」事情的相似度(SAM set启发式合并 二维数点)
只会后缀数组+暴躁莫队套set\(n \sqrt{n} \log n\)但绝对跑不过去。
attack
2019/04/01
5980
洛谷P4360 [CEOI2004]锯木厂选址(dp 斜率优化)
题意 题目链接 Sol 枚举第二个球放的位置,用前缀和推一波之后发现可以斜率优化 // luogu-judger-enable-o2 #include<bits/stdc++.h> #define Pair pair<int, int> #define MP(x, y) make_pair(x, y) #define fi first #define se second #define int long long #define LL long long #define Fin(x) {freopen
attack
2019/01/03
5620
洛谷P4492 [HAOI2018]苹果树(组合数)
题意 题目链接 Sol 有点自闭,。我好像对组合数一窍不通(~~~~) Orz shadowice // luogu-judger-enable-o2 #include<bits/stdc++.h>
attack
2019/03/11
3630
洛谷P4577 [FJOI2018]领导集团问题(dp 线段树合并)
因为后缀max是单调不升的,那么我们可以维护他的差分数组(两个差分数组相加再求和 与 对两个原数组直接求和是一样的)
attack
2019/03/11
6050
洛谷P4065 [JXOI2017]颜色(线段树)
所以我们可以对于每个右端点,统计最长的左端点在哪里,刚开始以为这个东西有单调性,但事实并不是这样。。
attack
2019/03/11
4350
洛谷P2664 树上游戏(点分治)
考虑点分治,那么每次我们只需要统计以当前点为\(LCA\)的点对之间的贡献以及\(LCA\)到所有点的贡献。
attack
2019/04/09
5580
推荐阅读
相关推荐
洛谷P4063 [JXOI2017]数列(dp)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档