[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 opposable thumbs. Unfortunately, none of the other cows in the herd are good opponents. They are so bad, in fact, that they always play in a completely predictable fashion! Nonetheless, it can still be a challenge for Bessie to figure out how to win.
Bessie and her friend Elsie are currently playing a simple card game where they take a deck of 2N2N2N cards, conveniently numbered 1…2N1 \ldots 2N1…2N , and divide them into NNN cards for Bessie and NNN cards for Elsie. The two then play NNN rounds, where in each round Bessie and Elsie both play a single card. Initially, the player who plays the highest card earns a point. However, at one point during the game, Bessie can decide to switch the rules so that for the rest of the game, the player who plays the lowest card wins a point. Bessie can choose not to use this option, leaving the entire game in "high card wins" mode, or she can even invoke the option right away, making the entire game follow the "low card wins" rule.
Given that Bessie can predict the order in which Elsie will play her cards, please determine the maximum number of points Bessie can win.
贝西很喜欢玩一种纸牌游戏。
贝西和她的朋友艾尔西正在玩这个简单的纸牌游戏。游戏有2N张牌,牌上的数字是1到2N。把这些牌分成两份,贝西有N张,艾尔西有另外N张。接下来她们进行N轮出牌,每次各出一张牌。一开始,谁出的牌上的数字大,谁就获得这一轮的胜利。贝西有一个特殊权利,她可以在任意一个时刻把原本数字大的获胜的规则改成数字小的获胜,这个改变将会一直持续到游戏结束。特别的,贝西可以从第一轮开始就使用小牌获胜的规则,也可以直到最后一轮都还杂使用大牌获胜的规则。
现在,贝西已经知道了艾尔西出牌的顺序,她想知道她最多能够赢多少轮。
输入输出格式
输入格式:The first line of input contains the value of N ( 2≤N≤50,0002 \leq N \leq 50,0002≤N≤50,000 ).
The next N lines contain the cards that Elsie will play in each of the
successive rounds of the game. Note that it is easy to determine Bessie's cards
from this information.
输出格式:Output a single line giving the maximum number of points Bessie can score.
输入输出样例
4 1 8 4 3
3
说明
Here, Bessie must have cards 2, 5, and 6, and 7 in her hand, and she can use
these to win at most 3 points. For example, she can defeat the 1 card and then
switch the rules to "low card wins", after which she can win two more rounds.
提交地址 : Bzoj4391
F1[i] 表示从头开始按照方案一的最大赢的数;
F2[i] 表示从胃开始按照方案二的最大赢的数;
那么答案就是max(F1[i] + F2[i+1]);
合理性分析:
(坑)
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <set> using namespace std; #define regi register int n, k; int a[50010], b[50010], cnt; int use[100010]; int f1[50010], f2[50010]; set <int> s1, s2; int main() { cin >> n; for (regi int i = 1 ; i <= n ; i ++){ scanf("%d", &b[i]); use[b[i]] = 1; } for (regi int i = 1 ; i <= 2 * n ; i ++){ if (!use[i]) { a[++cnt] = i; s1.insert(i); s2.insert(-i); } } for (register int i = 1 ; i <= n ; i ++){ set <int> :: iterator it = s1.lower_bound(b[i]); if (it != s1.end()) { s1.erase(it); f1[i] = f1[i-1] + 1; } else { f1[i] = f1[i-1]; } } for (register int i = n ; i >= 1 ; i --){ set <int> ::iterator it = s2.lower_bound(-b[i]); if (it != s2.end()) { s2.erase(it); f2[i] = f2[i+1] + 1; } else { f2[i] = f2[i+1]; } } int ans = f2[1]; for (register int i = 1 ; i <= n ; i ++){ ans = max(ans, f1[i] + f2[i+1]); } /* for (regi int i = 1 ; i <= n ; ++i) { printf("%d ", f1[i]); } puts(""); for (register int i = 1 ; i <= n ; i ++) { printf("%d ", f2[i]); } puts("");*/ cout << ans << endl; return 0; }