Fox and Card Game
题面翻译
桌子上有 n n n 堆牌。每张牌上都有一个正整数。Ciel可以从任何非空牌堆的顶部取出一张牌,Jiro可以从任何非空牌堆的底部取出一张牌。Ciel先取,当所有的牌堆都变空时游戏结束。他们都想最大化他所拿牌的分数(即每张牌上正整数的和)。问他们所拿牌的分数分别是多少?
题目描述
Fox Ciel is playing a card game with her friend Fox Jiro. There are $ n $ piles of cards on the table. And there is a positive integer on each card.
The players take turns and Ciel takes the first turn. In Ciel’s turn she takes a card from the top of any non-empty pile, and in Jiro’s turn he takes a card from the bottom of any non-empty pile. Each player wants to maximize the total sum of the cards he took. The game ends when all piles become empty.
Suppose Ciel and Jiro play optimally, what is the score of the game?
输入格式
The first line contain an integer $ n $ ( $ 1<=n<=100 $ ). Each of the next $ n $ lines contains a description of the pile: the first integer in the line is $ s_{i} $ ( $ 1<=s_{i}<=100 $ ) — the number of cards in the $ i $ -th pile; then follow $ s_{i} $ positive integers $ c_{1} $ , $ c_{2} $ , …, $ c_{k} $ , …, $ c_{si} $ ( $ 1<=c_{k}<=1000 $ ) — the sequence of the numbers on the cards listed from top of the current pile to bottom of the pile.
输出格式
Print two integers: the sum of Ciel’s cards and the sum of Jiro’s cards if they play optimally.
样例 #1
样例输入 #1
2
1 100
2 1 10
样例输出 #1
101 10
样例 #2
样例输入 #2
1
9 2 8 6 5 9 4 7 1 3
样例输出 #2
30 15
样例 #3
样例输入 #3
3
3 1 3 2
3 5 4 6
2 8 7
样例输出 #3
18 18
样例 #4
样例输入 #4
3
3 1000 1000 1000
6 1000 1000 1000 1000 1000 1000
5 1000 1000 1000 1000 1000
样例输出 #4
7000 7000
提示
In the first example, Ciel will take the cards with number 100 and 1, Jiro will take the card with number 10.
In the second example, Ciel will take cards with numbers 2, 8, 6, 5, 9 and Jiro will take cards with numbers 4, 7, 1, 3.
前不久刚把SAM题单刷完,最近开始刷博弈题单了,因为感觉博弈论很需要思考,而且我也不太会,感觉对我帮助比较大。
直接考虑每一堆牌最后是怎么被分割的,手玩发现每个人都可以保护靠近自己的一半不会被对手选择。那么问题来了,如果某个人选择靠近了对手的牌,比选择靠近自己的牌更好,那么对手肯定不愿意,因此每个人都只能选择靠近自己的牌。
那么我们把奇数堆中间的牌取出来,然后两个人轮流取走最大的即可。
#include <bits/stdc++.h>
#define ll long long
using namespace std;int main() {// freopen("in.in", "r", stdin);ios::sync_with_stdio(false);cin.tie(nullptr);int n;cin >> n;vector<int> a;int s1 = 0, s2 = 0;for (int i = 1; i <= n; i++) {int k; cin >> k;for (int j = 1; j <= k / 2; j++) {int t; cin >> t;s1 += t;}if (k & 1) {int x; cin >> x;a.push_back(x);}for (int j = 1; j <= k / 2; j++) {int t; cin >> t;s2 += t;}}sort(a.begin(), a.end());reverse(a.begin(), a.end());for (int i = 0; i < a.size(); i++) {if (i & 1) s2 += a[i];else s1 += a[i];}cout << s1 << " " << s2 << endl;
}