hud 4415 Assassin’s Creed

呼,终于对了,真是太粗心了。。。。。。

http://acm.hdu.edu.cn/showproblem.php?pid=4415

题意:一个人开始时有m个能量,他要杀死n个人,杀死每个人需要消耗能量为ai,杀死这个人后可以使用这个人的武器杀死bi个人,为怎样才能消耗最少的能量杀最多的人。

思路:贪心,比赛的时候根本没想用什么算法,只是按自己的想法写代码,怎么也不过,赛后问了一下队友,然后才觉得自己的想法还是有错误的。按队友的思路写了一个程序却怎么都是WA。最后发现原来是当Bi不为0的人都杀完后忘了加用武器杀死Bi为0的人的个数,呃,无奈啊。。

将n个人按Bi是否为0分别存在两个数组中,如果Bi不为0的数组有一个人能消耗能量杀死,那么所有不为0的人都能被杀死,然后处理Bi为0的人,在上一组中Bi未用完的可以继续杀死人,如果用完了,那就用能量来杀死,关键在于,Bi不为0的人除了第一个,其他人可以被武器杀死,也可以用能量杀死,如果他用能量杀死,那么武器就可以多杀死一个Bi为0 的人,所以在这一步就是比较Bi不为0的和Bi为0的那个消耗的能量更少了。还有一点,全部用能量杀死的人是否不通过武器消耗的能量多,这点要特殊判断。

呃,这题就是靠细心啊,考虑问题太不仔细了。。。。。。

代码:

View Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#define  N 100005
using namespace std ;

int a[N] , b[N] ;
int s ;

int main()
{
    int cas , c , i ;
    int n , m , num , st , flag ;
    int numx , stx ;

    //freopen( "input.txt" , "r" , stdin );
    scanf ( "%d" , &cas );
    for ( c = 1 ; c <= cas ; c++ )
    {
        scanf ( "%d%d" , &n , &m ) ;
        s = 0 ;
        int id1 = 0 , id2 = 0 ;
        for ( i = 0 ; i < n ; i++ )
        {
            int x , y ;
            scanf ( "%d%d" , &x , &y );
            s += y ;//所有Bi的和
            if ( !y )
            a[id1++] = x ;//Bi为0 
            else
            b[id2++] = x ;//Bi不为0
        }
        int all = m ;

        if ( id1 )//对A、B数组排序
        sort ( a , a + id1 );
        if ( id2 )
        sort ( b , b + id2 );
        flag = 0 ;
        num = 0 ; st = 0 ;
        if ( b[0] <= m )//判断一下能否找到一个Bi不为0的开始点
        {
            num = id2 ;
            m -= b[0] ;
            st = b[0] ;
            b[0] = -1 ;
            flag = 1 ;
        }
        if ( !flag )//如果找不到,那么就只能完全用能量
        {
            for ( i = 0 ; i < id1 ; i++ )
            if ( a[i] <= m )
            {
                st += a[i] ;
                m -= a[i] ;
                num++ ;
            }
            else
            break ;
        }
        else
        {
            if ( s + 1 >= n )//否则,判断一下Bi的和是否可以不在消耗能量杀死所有的人
            {
                num = n ;
            }
            else
            {
                int nx = id1 + id2 - s - 2 ;//如果不能的话,继续找能杀死的最多的人
                num += ( s + 1 - id2 );//这里忘了加,WA了无数次啊
                for ( i = 0 ; i <= nx ; i++ )
                b[id2++] = a[i] ;
                sort ( b , b + id2 );
                for ( i = 1 ; i < id2 ; i++ )
                {
                    if ( num >= n )
                    break ;
                    if ( b[i] <= m )
                    {
                        num++ ;
                        m -= b[i] ;
                        st += b[i] ;
                    }
                    else
                    break ;
                }
            }
        }
        //判读一下仅用能量杀死的人数
        stx = 0 ;
        numx = 0 ;
        for ( i = 0 ; i < id1 ; i++ )
        {
             if( numx >= n )
             break ;
             if ( a[i] <= all )
             {
                 numx++ ;
                 all -= a[i] ;
                 stx += a[i] ;
             }
             else
             break ;
        }
        printf ( "Case %d: " , c );
        if ( numx > num || ( numx == num && stx < st ))
        printf ( "%d %d\n" , numx , stx );
        else
        printf ( "%d %d\n" , num , st );
    }
    return 0 ;
}
原文地址:https://www.cnblogs.com/misty1/p/2702140.html