BZOJ 3983 Takeover Wars 解题报告

我猜了一个结论,能合并就合并,到了必须要敌对交易的时候才进行敌对交易。

然后合并的话,肯定是拿最大的两个去合并。

至于敌对交易,肯定是干掉对方最大的公司才是有意义的。

于是各种分类讨论。。。看代码好了。。。

#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
#define N 100000 + 5

int _, n, m;
priority_queue <LL> Q[2];

inline LL getint()
{
    char ch = '
';
    for (; ch > '9' || ch < '0'; ch = getchar()) ;
    LL res = ch - '0';
    for (ch = getchar(); ch >= '0' && ch <= '9'; ch = getchar())
        res = (res << 3) + (res << 1) + ch - '0';
    return res;
}

inline bool Solve()  // 返回赢家的编号 (0 或 1)
{
    for (int op = 0; ; op ^= 1)
    {
        if (Q[op].empty()) return op ^ 1; // Section 1 : 如果当前公司没有分公司了,自然赢家是对方。 
        if (Q[op].size() == 1) // Section 2 : 如果当前公司只剩一个分公司
        {
            if (Q[op].top() < Q[op ^ 1].top()) // Case 1 : 如果对方最值钱的公司比自己这个公司还值钱,自然赢家是对方。 
                return op ^ 1;
            else if (Q[op].top() == Q[op ^ 1].top() && Q[op ^ 1].size() == 1) // Case 2 : 两边都只剩一个分公司,而且价值都一样,那么平局,赢家算后手。 
                return 1;
            else if (Q[op].top() > Q[op ^ 1].top()) Q[op ^ 1].pop(); // Case 3 : 这里只能进行敌对交易。 
        }
        else // Section 3 : 如果当前公司有很多分公司 
        {
            LL Max_1 = Q[op].top();
            Q[op].pop();
            LL Max_2 = Q[op].top();
            Q[op].push(Max_1);
            if (Q[op ^ 1].size() == 1) // Case 1 : 如果对方只有一个分公司,那么当前公司只管合并就行了。 
            {
                Q[op].pop(), Q[op].pop();
                Q[op].push(Max_1 + Max_2);
            }
            else
            {
                LL _Max_1 = Q[op ^ 1].top();
                if (_Max_1 >= Max_1)  // Case 2 : 如果当前公司最大的分公司不及对方最大的分公司,那么只能合并。 
                {
                    Q[op].pop(), Q[op].pop();
                    Q[op].push(Max_1 + Max_2);
                }
                else
                {
                    Q[op ^ 1].pop();
                    LL _Max_2 = Q[op ^ 1].top();
                    Q[op ^ 1].push(_Max_1);
                    if (_Max_1 + _Max_2 >= Max_1 + Max_2)
                    {    // Case 3 : 如果当前公司前两大的分公司价值和小于等于对方前两大的分公司价值和,那必须要敌对交易了,否则主动权就不在自己这边了。 
                        Q[op ^ 1].pop();
                    }
                    else // Case 4 : 如果当前公司前两大的分公司价值和大于对方前两大的分公司价值和,那么就算合并了主动权也在自己这边,那就合并呗。 
                    {
                        Q[op].pop(), Q[op].pop();
                        Q[op].push(Max_1 + Max_2);
                    }
                }
            }
        }
    }
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("3983.in", "r", stdin);
        freopen("3983.out", "w", stdout);
    #endif
    
    while (scanf("%d%d", &n, &m) == 2)
    {
        while (!Q[0].empty()) Q[0].pop();
        while (!Q[1].empty()) Q[1].pop();
        for (int i = 1; i <= n; i ++) Q[0].push(getint());
        for (int i = 1; i <= m; i ++) Q[1].push(getint());
        bool winner = Solve();
        printf("Case %d: ", ++ _);
        puts(winner == 0 ? "Takeover Incorporated" : "Buyout Limited");
    }
    
    #ifndef ONLINE_JUDGE
        fclose(stdin);
        fclose(stdout);
    #endif
    return 0;
}
原文地址:https://www.cnblogs.com/gromah/p/4423132.html