hdu 6563 贪心

Strength

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 111 Accepted Submission(s): 95

Problem Description
Strength gives you the confidence within yourself to overcome any fears, challenges or doubts. Feel the fear and do it anyway! If you have been going through a rough time and feel burnt out or stressed, the Strength card encourages you to find the strength within yourself and keep going. You have got what it takes to see this situation through to its eventual end. You might also feel compelled to hold space for someone else who is going through a difficult period and needs your strength and support.

Alice and Bob are playing “Yu-Gi-Oh!”, a famous turn-based trading card game, in which two players perform their turns alternatively. After several turns, Alice and Bob have many monsters respectively.
Alice has n and Bob has m monsters under their own control. Each monster’s strength is measured by a non-negative integer si . To be specific, the larger si is, the more power the monster has.
During each turn, for every single monster under control, the player can give a command to it at most once, driving it to battle with an enemy monster (given that opposite player has no monsters as a shield, the monster can directly attack him).
Additionally, the process of the battle is also quite simple. When two monsters battle with each other, the stronger one (i.e. the one with larger si) will overwhelm the other and destroy it and the winner’s strength will remain unchanged. Meanwhile, the difference of their strength will produce equivalent damage to the player who loses the battle. If the player is directly attacked by a monster, he will suffer from the damage equal to the monster’s strength. Notice that when two monsters have the same strength, both of them will vanish and no damage will be dealt.
Right now it is Alice’s turn to play, having known the strength of all monsters, she wants to calculate the maximal damage she can deal towards Bob in one turn. Unfortunately, Bob has great foresight and is well-prepared for the upcoming attack. Bob has converted several of his monsters into defense position,
in which even if the monster is destroyed, he wouldn’t get any damage.
Now you are informed of the strength of all the monsters and whether it is in defense position for each Bob’s monster, you are expected to figure out the maximal damage that could be dealt in this turn.

Input
The first line contains a single integer T ≤ 20 indicating the number of test cases.
For each test case, the first line includes two integer 0 ≤ n, m ≤ 100000, representing the number of monsters owned by Alice and Bob.
In next three lines, the first two lines include n and m integers 0 ≤ si ≤ 109 indicating the strength of the i-th monster, separated by spaces. The last line contains m integers 0 or 1 indicating the position of Bob’s i-th monsters.In other words, 0 represents the normal position and 1 represents the defense position.

Output
For the ith test, output a single line in beginning of “Case i:”, followed by an integer indicating the answer, separated by a single space.

Sample Input
2
4 2
10 10 10 20
5 15
0 1
4 2
10 10 10 20
5 25
0 1

Sample Output
Case 1: 25
Case 2: 15

Source
2018CCPC吉林赛区(重现赛)- 感谢北华大学

题意:

有Alice和Bob两个人在玩游戏王,Alice场上有N个怪兽,Bob有M个怪兽,轮到了Alice回合,问Alice对Bob造成最大的伤害是多少?

思路:

有两个决策的办法。

  1. 不破坏Bob防守态的怪兽,直接攻击他的所有能攻击的怪兽。
  2. 破坏掉Bob防守态的怪兽,再对剩下的怪兽攻击,攻击完所有怪兽之后攻击本人。

两个决策中取最优的就行。

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
struct node
{
    int v,pos;
}a[maxn],b[maxn];
bool cmp(node a,node b)
{
    if(a.pos!=b.pos)
        return a.pos<b.pos;
    return a.v<b.v;
}
int findx(int n,int v)
{
    int l=1,r=n,mid,ans=inf;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(a[mid].v>=v)
        {
            if(a[mid].pos==0)
            {
                ans=mid;
            }
            r=mid-1;
        }
        else
        {
            l=mid+1;
        }
    }
    return ans;
}
int main()
{
    int t,cas=1,n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i].v);
            a[i].pos=0;
        }
        for(int i=1;i<=m;i++)
            scanf("%d",&b[i].v);
        for(int i=1;i<=m;i++)
            scanf("%d",&b[i].pos);
        sort(b+1,b+1+m,cmp);
        sort(a+1,a+1+n,cmp);
        int p=n,q=m;
        ll sum=0;
        ll tmp=0;
        //1 直接攻击它的所有攻击态的
        while(q&&b[q].pos==1) q--;
        while(p&&q)
        {
            if(a[p].v>=b[q].v)
            {
                tmp=tmp+a[p].v-b[q].v;
                p--,q--;
            }
            else break;
        }
        sum=max(tmp,sum);

        //2 先贪心的将它的防御的攻击掉,再攻击剩下的
        p=n,q=m,tmp=0;
        int f=1;
        while(q&&b[q].pos==1)
        {
            int pos=findx(n,b[q].v);
            if(pos==inf)
            {
                f=0;
                break;
            }
            a[pos].pos=1;
            q--;
        }
        int ff=1;
        if(f)
        {
            while(q&&p)
            {
                if(a[p].pos==1) p--;
                else
                {
                    if(a[p].v>=b[q].v)
                    {
                        tmp=tmp+a[p].v-b[q].v;
                        p--,q--;
                    }
                    else
                    {
                        ff=0;
                        break;
                    }
                }
            }
            if(ff)
            {
                while(p)
                {
                    if(a[p].pos==1) p--;
                    else
                    {
                        tmp=tmp+a[p].v;
                        p--;
                    }
                }
            }
            sum=max(sum,tmp);
        }
        printf("Case %d: %lld\n",cas++,sum);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值