首页 > 其他分享 >C. Card Game

C. Card Game

时间:2023-10-10 17:13:18浏览次数:30  
标签:下标 删除 元素 will Game score cards Card

C. Card Game

There are $n$ cards stacked in a deck. Initially, $a_{i}$ is written on the $i$-th card from the top. The value written on a card does not change.

You will play a game. Initially your score is $0$. In each turn, you can do one of the following operations:

  • Choose an odd$^{\dagger}$ positive integer $i$, which is not greater than the number of cards left in the deck. Remove the $i$-th card from the top of the deck and add the number written on the card to your score. The remaining cards will be reindexed starting from the top.
  • Choose an even$^{\ddagger}$ positive integer $i$, which is not greater than the number of cards left in the deck. Remove the $i$-th card from the top of the deck. The remaining cards will be reindexed starting from the top.
  • End the game. You can end the game whenever you want, you do not have to remove all cards from the initial deck.

What is the maximum score you can get when the game ends?

$^{\dagger}$ An integer $i$ is odd, if there exists an integer $k$ such that $i = 2k + 1$.

$^{\ddagger}$ An integer $i$ is even, if there exists an integer $k$ such that $i = 2k$.

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 10^{4}$). The description of the test cases follows.

The first line of each test case contains a single integer $n$ ($1 \le n \le 2 \cdot 10^{5}$).

The second line of each test case contains $n$ integers $a_1, a_2, \ldots, a_n$ ($-10^{9} \le a_i \le 10^{9}$).

It is guaranteed that the sum of $n$ over all test cases does not exceed $2 \cdot 10^{5}$.

Output

For each test case, print a single integer — the maximum score you can get when the game ends.

Example

input

4
4
-4 1 -3 5
4
1 -2 3 -4
3
-1 3 -5
1
-1

output

5
4
2
0

Note

In the first test case, one can get the score of $5$ as follows:

  1. In the first turn, choose $i=2$. Your score remains $0$ and the numbers written on the cards from the top will become $[-4, -3, 5]$.
  2. In the second turn, choose $i=3$. Your score will become $5$ and the numbers written on the cards from the top will become $[-4, -3]$.
  3. In the third turn, end the game with the score of $5$.

In the second test case, one can get the score of $4$ as follows:

  1. In the first turn, choose $i=3$. Your score will become $3$ and the numbers written on the cards from the top will become $[1, -2, -4]$.
  2. In the second turn, choose $i=1$. Your score will become $4$ and the numbers written on the cards from the top will become $[-2, -4]$.
  3. In the third turn, end the game with the score of $4$.

In the third test case, one can get the score of $2$ as follows:

  1. In the first turn, choose $i=1$. Your score will become $-1$ and the numbers written on the cards from the top will become $[3, -5]$.
  2. In the second turn, choose $i=1$. Your score will become $2$ and the numbers written on the cards from the top will become $[-5]$.
  3. In the third turn, end the game with the score of $2$.

 

解题思路

  一开始的做法是 dp,没想到贪心。不过这个 dp 的思考过程还挺麻烦的。

  定义状态 $f(i,j)$ 表示从前 $i$ 个元素中删除了 $j$ 个的所有方案里分数的最大值。根据第 $i$ 元素是否删除来进行状态划分:

  1. 如果不删除第 $i$ 个元素,那么有 $f(i,j) = f(i-1,j)$。
  2. 如果删除第 $i$ 个元素,分三种情况:
    • $j = 0$:无法删除第 $i$ 个元素,有 $f(i,j) = f(i-1,j)$。
    • $j = 1$:由于至少要删除 $1$ 个元素,且要删除第 $i$ 个元素,因此只能删除第 $i$ 个元素,是否获得 $a_i$ 的分数只取决于 $i$ 的奇偶性,有 $f(i,j) = f(i-1,j-1) + (i \bmod 2) \cdot a_i$。
    • $j \geq 2$:如果 $a_i > 0$,为了获取分数,$i$ 是奇数的话可以先删除第 $i$ 个元素,再从前 $i-1$ 个元素中删除 $j-1$ 个元素;$i$ 是偶数的话可以先从前 $i-1$ 个元素中删除 $1$ 个元素,再删除原本的第 $i$ 个元素,然后再从原本的前 $i-1$ 个元素中删除 $j-2$ 个元素。如果 $a_i < 0$,同理,我们要将其变到偶数的下标再删除。有 $f(i,j) = f(i-1,j-1) + \max \{ 0, a_i \}$。

  为此就有状态转移方程:$$\begin{cases} f(i,0) = f(i-1,0) ,& j = 0 \\ f(i,1) = \max \{ f(i-1,1), \, f(i-1,0) + (i \bmod 2) \cdot a_i \} ,& j=1 \\ f(i,j) = \max \{ f(i-1,j), \, f(i-1,j-1) + \max \{ 0, a_i \} \} ,& j \in [2,n] \end{cases}$$

  那么最终答案就是 $\max\limits_{0 \leq i \leq n}{\{ f(n,i) \}}$。整个 dp 的时间复杂度为 $O(n^2)$,很明显会超时。可以发现其实我们只关注 $j$ 的三种情况:$j=0$,$j=1$,$j \geq 2$,而并不需要知道 $j$ 的确切值。为此我们直接把 $j$ 的所有可能取值压缩成 $3$ 种状态:$f(i,0)$ 表示从前 $i$ 个元素中删除 $0$ 个的所有方案里分数的最大值。$f(i,1)$ 表示从前 $i$ 个元素中删除恰好 $1$ 个的所有方案里分数的最大值。$f(i,2)$ 表示从前 $i$ 个元素中删除至少 $2$ 个的所有方案里分数的最大值。

  状态转移方程直接对着上面改就可以了:$$\begin{cases} f(i,0) = f(i-1,0) \\ f(i,1) = \max \{ f(i-1,1), \, f(i-1,0) + (i \bmod 2) \cdot a_i \} \\ f(i,2) = \max \{ f(i-1,2), \, \max \{ f(i-1,1), f(i-1,2) \} + \max \{ 0, a_i \} \} \end{cases}$$

  AC代码如下,时间复杂度为 $O(n)$:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 2e5 + 10;
 7 
 8 int a[N];
 9 LL f[N][3];
10 
11 void solve() {
12     int n;
13     scanf("%d", &n);
14     for (int i = 1; i <= n; i++) {
15         scanf("%d", a + i);
16     }
17     f[0][0] = 0, f[0][1] = f[0][2] = -0x3f3f3f3f3f3f3f3f;
18     for (int i = 1; i <= n; i++) {
19         f[i][0] = f[i - 1][0];
20         f[i][1] = max(f[i - 1][1], f[i - 1][0] + i % 2 * a[i]);
21         f[i][2] = max(f[i - 1][2], max(f[i - 1][1], f[i - 1][2]) + max(0, a[i]));
22     }
23     printf("%lld\n", max({f[n][0], f[n][1], f[n][2]}));
24 }
25 
26 int main() {
27     int t;
28     scanf("%d", &t);
29     while (t--) {
30         solve();
31     }
32     
33     return 0;
34 }

  然后再给出官方的贪心解法。

  这里规定原序列中 $a_0$ 表示栈顶元素,$a_n$ 是栈底元素,即栈的开口在下标最小的处。

  首先答案至少是 $0$,即一个元素都不删除的情况。否则至少要删除一个元素,对于所有的删除方案,这里按照中被删除元素的最小下标来进行分类,因此可以分成 $n$ 类。

  假设被删除元素的最小下标是 $i$,那么在原序列中不可能再从 $[1,i-1]$ 中删除元素(获得分数),并且一定能够获得 $[i+1,n]$ 中所有的正整数分数。构造的方法如下,在删除的过程中只要在比 $i$ 大的下标里存在某个奇数下标是正整数,那么删除这个元素并获得分数,直到所有的奇数下标都不是正整数。此时偶数下标可能存在正整数,那么只要删除了第 $i$ 个元素,就会变成奇数下标,那么只需从最大的下标开始依次往前删除即可获得所有的正整数分数。而删除第 $i$ 个元素后从奇数下标变成的偶数下标不会再有正整数。

  为此只需维护一个后缀和,然后枚举所有的 $i$ 作为被删除元素的最小下标,取所有情况的最大值即可。

  AC 代码如下,时间复杂度为 $O(n)$:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 2e5 + 10;
 7 
 8 int a[N];
 9 LL s[N];
10 
11 void solve() {
12     int n;
13     scanf("%d", &n);
14     for (int i = 1; i <= n; i++) {
15         scanf("%d", a + i);
16     }
17     s[n + 1] = 0;
18     for (int i = n; i; i--) {
19         s[i] = s[i + 1] + max(0, a[i]);
20     }
21     LL ret = 0;
22     for (int i = 1; i <= n; i++) {
23         ret = max(ret, s[i + 1] + i % 2 * a[i]);    // 由于必须删除a[i],因此如果i是奇数则a[i]的分数必须获得
24     }
25     printf("%lld\n", ret);
26 }
27 
28 int main() {
29     int t;
30     scanf("%d", &t);
31     while (t--) {
32         solve();
33     }
34     
35     return 0;
36 }

 

参考资料

  Codeforces Round 899 (Div. 2) Editorial:https://codeforces.com/blog/entry/120792

  Codeforces Round 899 (Div. 2) A~D:https://zhuanlan.zhihu.com/p/658393910

标签:下标,删除,元素,will,Game,score,cards,Card
From: https://www.cnblogs.com/onlyblues/p/17755146.html

相关文章

  • [ARC155D] Avoid Coprime Game
    [ARC155D]AvoidCoprimeGame一个暴力思路是直接记录选了哪些\(a\)然后转移,但是我们显然没办法将已选择的\(a\)的信息用状压全部记录下来。但是你注意到题目中对\(a\)的选择有着不错的性质,具体如下:若确定当前\(G\),则先前选择的所有\(a_i\)均满足\(G|a_i\)。若经......
  • gameofmir引擎白手版跟商业版的区别
    1商业版自定义界面功能可以保存配置2商业版登录器支持读取二次加密的Pak。需购买Pak二次加密工具。3商业版增加数字证书,防止杀毒软件误报4商业版支持163博客远程列表,列表首尾需$BEGIN$END关键字5商业版支持聊天框背景颜色自定义6商业版支持新技能纵横剑术、十步一杀、冰镰术、冰......
  • [CF1854E] Game Bundles
    题目描述Rishiisdevelopinggamesinthe2Dmetaverseandwantstooffergamebundlestohiscustomers.Eachgamehasanassociatedenjoymentvalue.Agamebundleconsistsofasubsetofgameswhosetotalenjoymentvalueaddsupto$60$.Yourtaskistoc......
  • AtCoder Grand Contest 056 D Subset Sum Game
    洛谷传送门AtCoder传送门考虑若\(n\)是奇数怎么做。枚举Alice第一次选的数\(a_i\),然后考虑把剩下的数两两结成一个匹配,若Bob选了其中一个,Alice就选另一个。容易发现排序后奇数位和它右边的偶数位匹配最优。那么设奇数位的和为\(A\),偶数位的和为\(B\),此时Alice获胜......
  • CF1875B Jellyfish and Game
    思路题意大概是两人都有一组数,奇数轮,第一个人可以选择和第二个人交换一个数字也可以不换,偶数轮,第二个人可以选择和第一个人交换一个数字也可以不换。首先可以猜测,我们每次都应该选择交换对方的最大值和自己的最小值,如果自己的最小值都比对方大的话就不交换。应该比较好想,这里感......
  • UTPC 2021 L Maze Game
    洛谷传送门AtCoder传送门若图中存在点使得删去它后\(S,T\)不连通,那么A可以一步获胜。否则,双方都不会删去一个点使得删去它后会产生一个点使得删去它后\(S,T\)不连通。那么到最后图上会剩下两条\(S\toT\)的不交路径。此时一方无论如何操作都会使得另一方获胜。因......
  • Galgame封包逆向入门
    Galgame封包逆向入门这里就简单聊一下封包逆向分析的一些注意点吧,其实也是初入逆向的注意点了,本质差不多。正向基础语言基础:ASM、C、C++平台基础:Win32、PE、GDI、DirectX引擎基础:游戏引擎架构虽然说的逆向,其实和正向的水平、见识、经验是强相关的,如果你没写过相关的程序又......
  • GameFi链游系统开发应用
      GameFi软件的开发是结合了区块技术,它是将游戏的元素移动到上链上,让游戏变得独立,这就符合了用户的娱乐方式。该软件项目还具有一定的投资价格,GameFi系统开发的应用可以带来更多的创新和价值。  GameFi的软件开发应用程序是让用户更好的管理自己的资产,有助于游戏的稳定,持......
  • CF1882C Card Game
    某种程度上的抽卡游戏?有这样一个结论:一个后缀中\([i+1,n]\)中所有的正数都可以被取到,所以维护一个正数后缀和\(s_i\),枚举每个位置\(i\),如果\(i\)为奇数,答案对\(a_i+s_{i+1}\)取\(\max\),否则对\(s_{i+1}\)取\(\max\)。下面证明这个结论:先依次取掉\([i+1,n]\)中的奇......
  • Black-Box Attack-Based Security Evaluation Framework forCredit Card Fraud Detect
    Black-BoxAttack-BasedSecurityEvaluationFrameworkforCreditCardFraudDetectionModels动机AI模型容易受到对抗性攻击(对样本添加精心设计的扰动生成对抗性示例)现有的对抗性攻击可以分为白盒攻击和黑盒攻击。白盒攻击:攻击者可以访问有关目标模型的所有信息,包括训练集......