~~~题面~~~

题解:

  观察到以决策点为分界线,以点数大的赢为比较方式的游戏都是它的前缀,反之以点数小的赢为比较方式的都是它的后缀,也就是答案是由两段答案拼凑起来的。

  如果不考虑判断胜负的条件的变化,则有一个比较容易发现的贪心:

  设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 贪心 线段树的更多相关文章

  1. 【BZOJ4391】[Usaco2015 dec]High Card Low Card(贪心)

    [BZOJ4391][Usaco2015 dec]High Card Low Card(贪心) 题面 BZOJ 题解 预处理前缀后缀的结果,中间找个地方合并就好了. #include<iostr ...

  2. BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库

    正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...

  3. 【题解】P3129高低卡(白金)High Card Low Card

    [题解][P3129 USACO15DEC]高低卡(白金)High Card Low Card (Platinum) 考虑贪心. 枚举在第几局改变规则,在改变规则之前,尽量出比它大的最小的牌,在改变规 ...

  4. 【题解】P1712 [NOI2016]区间(贪心+线段树)

    [题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...

  5. [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 ...

  6. 【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 ...

  7. 【刷题】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 ...

  8. [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 ...

  9. Codeforces 675E Trains and Statistic(DP + 贪心 + 线段树)

    题目大概说有n(<=10W)个车站,每个车站i卖到车站i+1...a[i]的票,p[i][j]表示从车站i到车站j所需买的最少车票数,求所有的p[i][j](i<j)的和. 好难,不会写. ...

随机推荐

  1. eclipse插件SCON的SConscript文件和头文件以及C文件包含路径

    1. 本次的头文件路径\Hi2110-B657SP3-SDK\src_release_657SP3\src\lib\onenet\public,以此例子作为研究,本次开发使用eclipse,用到SCO ...

  2. MySQL高级-索引优化

    索引失效 1. 2.最佳左前缀法则 4. 8. 使用覆盖索引解决这个问题. 二.索引优化 1.ORDER BY 子句,尽量使用Index方式排序,避免使用FileSort方式排序 MySQL支持两种方 ...

  3. Python 默认参数值

    Python 默认参数值,对于一些函数来说,你可能为希望使一些参数可选并使用默认的值,以避免用户不想为他们提供值的情况.默认参数值可以有效帮助解决这一情况.你可以通过在函数定义时附加一个赋值运算符(= ...

  4. 进度条加载与案例优化对比——python使用perf_count方法实现

    本章我们将讨论python3 perf_counter()的用法及它的实际应用我从中选取两个python基于rquests库的爬虫实例代码源文件进行举例 Python3 perf_counter() ...

  5. ajax 个人理解 学习笔记

    W:Ajax Q:异步网络请求.无刷新请求数据. W:ajax的实现流程如下: Q: 创建XHR对象 调用open()方法,创建请求 调用send()方法,发送请求 捕获请求状态,判断请求结果 获取数 ...

  6. @ConfigurationProperties注解对数据的自动封装

    @ConfigurationProperties注解对数据的自动封装 @ConfigurationProperties可以对基本数据类型实现自动封装,可以封装格式为yyyy/MM/dd的日期 测试代码 ...

  7. 关于GitHub推送时发生Permission denied (publickey)的问题

    今天在学习廖雪峰老师官网的git教程“添加远程库”时发现总是推送失败,下边提示“Permission denied (publickey) 这个问题” 传送门:https://www.liaoxuef ...

  8. 【转载】2015Android 面试题 01

    1.如何避免ANR? 答:ANR:Application Not Responding,五秒在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应. 当出现下列情况时,Andr ...

  9. 软件工程第二周PSP

  10. Thunder团队第五周 - Scrum会议4

    Scrum会议4 小组名称:Thunder 项目名称:i阅app Scrum Master:李传康 工作照片: 邹双黛同学在拍照,所以不在照片内. 参会成员: 王航:http://www.cnblog ...