Codeforces 388C Fox and Card Game 博弈

题目大意:

现在Ciel和Jiro玩一个游戏

初始状态的时候桌子上面有n堆牌(1 <= n <= 100) 第i堆排有si (1 <= si <= 100) 张牌, 给出每张牌的值ck, (1 <= ck <= 1000)

Ciel先手, 每次可以选择一个非空的牌堆中拿走最上面的一张牌, Jiro后手每次选择一个非空的牌堆拿走最下面的一张牌, 两者都想使得自己得到的牌的和尽量大, 求在Ciel和Jiro都采取最优策略的情况下两者的分数


大致思路:

首先对于一个偶数张牌的堆, 当两者都采取最优策略的时候, Ciel会拿走上面的一半, 而Jiro会拿走下面的一半, 这是因为, Ciel在这样一堆牌中不能赢得更多, 每次Ciel选择这一堆牌时Jiro都可以在其拿下一张时, 拿到最下面的牌, 同样对于奇数堆来说上半部分会被Ciel获得, 下半部分被Jiro获得, 中间那张牌就成为竞争的对象, 在很多个奇数堆当中, 正中间那张牌将会成为竞争对象, 所以先手会抢得中间最大的牌, Jiro其次, Ciel再拿到第三大的牌, Jiro再其次...

所以要得到最优策略下两者的得分, 只需要对奇数堆中间的数排序即可


代码如下:

Result  :  Accepted     Memory  :  444 KB     Time  :  31 ms

/*
 * Author: Gatevin
 * Created Time:  2015/2/28 13:43:49
 * File Name: Shana.cpp
 */
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;

int n;
int s[110][1010];
int cnt[110];
vector <int> v;

int main()
{
    cin>>n;
    int ans1 = 0, ans2 = 0;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &cnt[i]);
        for(int j = 1; j <= cnt[i]; j++)
            scanf("%d", &s[i][j]);
        if(cnt[i] & 1)
        {
            v.push_back(s[i][(cnt[i] + 1) >> 1]);
            for(int j = 1; j <= cnt[i] / 2; j++) ans1 += s[i][j];
            for(int j = (cnt[i] + 1) / 2 + 1; j <= cnt[i]; j++) ans2 += s[i][j];
        }
        else
        {
            for(int j = 1; j <= cnt[i] / 2; j++) ans1 += s[i][j];
            for(int j = (cnt[i] / 2 ) + 1; j <= cnt[i]; j++) ans2 += s[i][j];
        }
    }
    sort(v.begin(), v.end(), greater<int>());
    for(unsigned int i = 0; i < v.size(); i++)
    {
        if(i & 1)
            ans2 += v[i];
        else ans1 += v[i];
    }
    cout<<ans1<<" "<<ans2<<endl;
    return 0;
}


你可能感兴趣的:(game,博弈,codeforces,and,card,Fox,388c)