[bzoj4391] [Usaco2015 dec]High Card Low Card 贪心 线段树
题解:
观察到以决策点为分界线,以点数大的赢为比较方式的游戏都是它的前缀,反之以点数小的赢为比较方式的都是它的后缀,也就是答案是由两段答案拼凑起来的。
如果不考虑判断胜负的条件的变化,则有一个比较容易发现的贪心:
设f[i]为从1开始到i位, 比较方式为点数大的获胜,最多能赢几局。
那么为了使答案尽可能优,每次我们都会在剩余牌中找到点数大于对方的 最小的牌,然后出掉。
同理,设g[i]为从n开始到i位,比较方式为点数小的获胜,最多能赢几局,
则每次都在剩余牌中选择点数小于对方的,最大的牌出掉,这样可以使得答案尽可能优。
最后的答案则是max(f[i] + g[i + 1]);
那么为什么这样一定就是合法的呢?
首先最优性应该是可以理解的,那么唯一会导致不合法的情况就是至少一张牌a,在两边的决策中都出现了(即被出掉了2次)。对于这种情况,任意一张a出掉了2次,因为游戏次数=牌数,所以必然还对应着一张b没有被出过。那么如果b > a,则用b来代替f[i]中的a一定合法,因为f[i]是点数大的获胜。反之,b < a, 则用b来代替g[i + 1]中的a一定合法,因为g[i]是点数小的获胜。
于是为了求出这2个数组,我们需要一个可以支持查询前驱后继和删除的数据结构。
你可以选择set,splay,线段树等等。
这里我因为不会用set,懒得写splay,所以选择了值域线段树。
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 100100
#define ac 1001000
#define inf INT_MAX int n, w, go, ans;
int tree[ac], maxn[ac], minn[ac], l[ac], r[ac];
int s[AC], f[AC], g[AC];
bool z[AC];//记录哪些牌在对方手里 inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} inline void upmax(int &a, int b)
{
if(b > a) a = b;
} void pre()
{
n = read();
for(R i = ; i <= n; i ++) s[i] = read(), z[s[i]] = true;
} inline void update(int x)
{
int ll = x * , rr = ll + ;
tree[x] = tree[ll] + tree[rr];
maxn[x] = max(maxn[ll], maxn[rr]);
minn[x] = min(minn[ll], minn[rr]);
} void build(int x, int ll, int rr)
{
l[x] = ll, r[x] = rr;
if(ll == rr)
{
if(!z[ll])
tree[x] = , maxn[x] = ll, minn[x] = ll;
else minn[x] = inf;
return ;
}
int mid = (ll + rr) >> ;
build(x * , ll, mid);
build(x * + , mid + , rr);
update(x);
} void last(int x)//前驱
{
if(minn[x] > w) return ;
if(l[x] == r[x])
{
tree[x] = maxn[x] = , minn[x] = inf, go = ;
return ;
}
if(minn[x * + ] < w) last(x * + );
else last(x * );
update(x);
} void Next(int x)//后继
{
if(maxn[x] < w) return ;
if(l[x] == r[x])
{
tree[x] = maxn[x] = , minn[x] = inf, go = ;
return ;
}
if(maxn[x * ] > w) Next(x * );
else Next(x * + );
update(x);
} void work()
{
build(, , * n);
for(R i = ; i <= n; i ++)
{
w = s[i], go = , Next();
f[i] = f[i - ] + go;
}
build(, , * n);
for(R i = n; i; i --)
{
w = s[i], go = , last();
g[i] = g[i + ] + go;
}
/*for(int i = 1; i <= n; i ++) printf("%d ", f[i]);
printf("\n");
for(int i = 1; i <= n; i ++) printf("%d ", g[i]);
printf("\n");*/
for(R i = ; i <= n; i ++) upmax(ans, f[i] + g[i + ]);
printf("%d\n", ans);
} int main()
{
freopen("in.in", "r", stdin);
pre();
work();
fclose(stdin);
return ;
}
[bzoj4391] [Usaco2015 dec]High Card Low Card 贪心 线段树的更多相关文章
- 【BZOJ4391】[Usaco2015 dec]High Card Low Card(贪心)
[BZOJ4391][Usaco2015 dec]High Card Low Card(贪心) 题面 BZOJ 题解 预处理前缀后缀的结果,中间找个地方合并就好了. #include<iostr ...
- BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库
正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...
- 【题解】P3129高低卡(白金)High Card Low Card
[题解][P3129 USACO15DEC]高低卡(白金)High Card Low Card (Platinum) 考虑贪心. 枚举在第几局改变规则,在改变规则之前,尽量出比它大的最小的牌,在改变规 ...
- 【题解】P1712 [NOI2016]区间(贪心+线段树)
[题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...
- [BZOJ4391][Usaco2015 dec]High Card Low Card dp+set+贪心
Description Bessie the cow is a huge fan of card games, which is quite surprising, given her lack of ...
- 【dp 贪心】bzoj4391: [Usaco2015 dec]High Card Low Card
巧妙的贪心 Description Bessie the cow is a huge fan of card games, which is quite surprising, given her l ...
- 【刷题】BZOJ 4391 [Usaco2015 dec]High Card Low Card
Description Bessie the cow is a huge fan of card games, which is quite surprising, given her lack of ...
- [USACO15DEC]高低卡(白金)High Card Low Card (Platinum)
题目描述 Bessie the cow is a hu e fan of card games, which is quite surprising, given her lack of opposa ...
- Codeforces 675E Trains and Statistic(DP + 贪心 + 线段树)
题目大概说有n(<=10W)个车站,每个车站i卖到车站i+1...a[i]的票,p[i][j]表示从车站i到车站j所需买的最少车票数,求所有的p[i][j](i<j)的和. 好难,不会写. ...
随机推荐
- DMA是什么意思
DMA是让硬盘不用通过CPU来控制读写 它的意思是直接存储器存取,是一种快速传送数据的机制,DMA技术的重要性在于,利用它进行数据存取时不需要CPU进行干预,可提高系统执行应用程序的效率.利用DMA传 ...
- 使用vs code写php及调试
原文来自:http://www.cnblogs.com/CLR010/p/5276077.html 首页先改下php.ini 一般是在最底部,有就修改没有就加上去下面的配置: xdebug.remot ...
- 在ubuntu安装python, theano, keras , Spearmint, Mongodb
系统配置: Ubuntu 14 (其他系统也差不多如下操作) 1. 通过anaconda安装 python 地址: https://www.continuum.io/downloads#linux 2 ...
- 编译chromium时下载gn.exe时出错的解决方案
天朝人写个代码真难,想要编译一下chromium,但是获取代码时各种坑,不是网速慢,就是网络联不通,真难玩. 本文针对下载gn.exe等工具时失败的解决方案. 原因1:gclient没有走代理,针对使 ...
- 「日常训练」Uncle Tom's Inherited Land*(HDU-1507)
题意与分析 题意是这样的:给你一个\(N\times M\)的图,其中有一些点不能放置\(1\times 2\)大小的矩形,矩形可以横着放可以竖着放,问剩下的格子中,最多能够放多少个矩形. 注意到是\ ...
- 结合BeautifulSoup和hackhttp的爬虫实例
网页页数的改变 headers头不添加
- 接口测试工具postman(八)上传文件接口
涉及到选择文件的接口,在[Body]页签下,key选择File选项,会显示“选择文件”按钮,选择本地的文件
- 【C++模版之旅】项目中一次活用C++模板(traits)的经历 -新注解
问题与需求: 请读者先看这篇文章,[C++模版之旅]项目中一次活用C++模板(traits)的经历. 对于此篇文章提出的问题,我给出一个新的思路. talking is cheap,show me t ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第1章.Spring概述
第1章.Spring概述 Spring概述 The Spring Framework is a lightweight solution and a potential one-stop-shop f ...
- 【WXS数据类型】String
属性: 名称 值类型 说明 [String].constructor [String] 返回值为“String”,表示类型的结构字符串 [String].length [Number] 返回该字符串的 ...