CodeForces-388C-Fox and Card Game-一分为二的博弈

题目描述:

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 si (1 ≤ si≤ 100) — the number of cards in the i-th pile; then follow si positive integers c1, c2, …, ck, …, csi (1 ≤ ck ≤ 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.

输入样例:

3
3 1 3 2
3 5 4 6
2 8 7

输出样例:

18 18

核心思想:

双方轮流拿,每次拿一个。
对于某一堆,如果某一个人要越过中间那一个去拿就意味着受到了权值大的卡牌的吸引。然而两人步长一样,那个权值大的卡牌会被另外一个人(离得近)先拿到,故得证两人无法越过中间线去拿卡牌。
对于某一堆,上一半的卡牌由Ciel拿到,下一半的卡牌由Jiro拿到,如果这一堆数量为奇数,则将正中间的一张牌加入数组b中。
最后将数组b排序,两人从大到小轮流拿牌。

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1100;
int a[N],b[N],cb;
int main()
{
	int n,s,sum1=0,sum2=0;
	cin>>n;
	for(int i=0;i<n;i++){
		scanf("%d",&s);
		for(int i=1;i<=s;i++) scanf("%d",&a[i]);
		for(int i=1;i<=s/2;i++) sum1+=a[i];//上一半Ciel拿到 
		int st;//记录中间位置 
		if(s&1) {
			st=s/2+2;
			b[cb++]=a[st-1];//此堆奇数个,加入数组b 
		}
		else st=s/2+1;
		for(int i=st;i<=s;i++) sum2+=a[i];//下一半Jiro拿到	
	} 
	sort(b,b+cb);
	for(int i=cb-1;i>=0;i-=2) sum1+=b[i];
	for(int i=cb-2;i>=0;i-=2) sum2+=b[i];
	cout<<sum1<<' '<<sum2<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值