ZOJ 3474 Taekwondo

题目链接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3474
题解:
题意:
一个人要打跆拳道,他要打n个人,并且知道他的初始的能量m,然后n行,每行有m1,m2,m3 以及s,前面的三个表示打这个部位会消耗的能量,并且打m1会得到三分,打m2会得到2分,打m3只会得到一分,并且知道打到一个人需要7分,打倒这个人之后,你会得到s点能量,问你最后打到全部人之后剩余的最多的能量,如果不能打倒全部的人,就输出-1。
我们首先需要知道打到一个人需要消耗的最小的能量,这个最小能量可以直接去暴力求解,枚举7的由1,2,3可以组成的所有的情况,然后去取个最小的。难点是怎么能够判断能够打倒所有的人,这里可以使用贪心的方法,但是需要注意的是,我们在考虑的是怎么能够打倒所有的人,而不是打人需要的需要消耗的少的时间。
代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
const int  maxn = 100+10;
struct node
{
    int cost;
    int get;
}a[maxn],b[maxn];

int cmp1(node a,node b)
{
    return a.cost<=b.cost;
}

int cmp2(node a,node b)
{
    return a.get>=b.get;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        int len1=0;
        int len2=0;
        met(a,0);
        met(b,0);
        for(int i=0;i<n;i++)
        {
            int x,y,z,get;
            scanf("%d%d%d%d",&x,&y,&z,&get);
            int cost=inf;
            for(int k=0; k<=4; k++)
                for(int kk=0; kk<=4; kk++)
                    for(int kkk=0; kkk<=8; kkk++) {
                        int res=k*3+2*kk+kkk;
                        if(res>=7)
                            cost=min(cost,k*x+kk*y+kkk*z);
                    }
            //            cout<<get<<endl;
            if(get>cost)
            {
                a[len1].cost=cost;
                a[len1].get=get;
                len1++;
            }
            else
            {
                b[len2].cost=cost;
                b[len2].get=get;
                len2++;
            }
        }
        sort(a,a+len1,cmp1);
        sort(b,b+len2,cmp2);
        int flag=0;
        for(int i=0;i<len1;i++)
        {
            if(m<=a[i].cost)
            {
                flag=1;
                break;
            }
            m+=a[i].get-a[i].cost;
        }
        if(flag)
        {
            printf("no\n");
            continue;
        }
        flag=0;
        for(int i=0;i<len2;i++)
        {
            if(m<=b[i].cost)
            {
                flag=1;
                break;
            }
            m+=b[i].get-b[i].cost;
        }
        if(flag)
            printf("no\n");
        else
            printf("%d\n",m);
    }
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值