The Indian Job

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zjucor/article/details/82689167

这是著名的意大利抢劫——“偷天换日”的印度版本. N个劫匪已经闯入国家博物馆,并且准备进入装满珠宝的主展厅。他们非常幸运,因为他们闯入时,护卫正好要离开博物馆恰好G分钟。但是,还有别的问题。主展厅装有热传感器,所以再任何时刻主展厅里有超过两个人,警报器就会响。 为了收集珠宝,每个劫匪需要在主展厅停留连续的A[i]分钟, 0 <= i < N,现在劫匪们想知道是否存在一种抢劫安排,使得警报器不会响,他们不会被抓住。因为护卫会在G分钟后回来,他们必须G分钟之内完成任务。

注意 
如果一个劫匪进入,同时另外一个劫匪恰好出来,这并不算两个人同时在主展厅。 类似地,如果在护卫回来的G时刻,劫匪恰好离开,护卫也看不到劫匪。

输入格式 
第一行包含了一个整数T, 测试数据的数量。 
每组测试数据包含两行,第一行有两个空格分隔的整数N和_G_,劫匪数和护卫离开博物馆的时间长度。下一行包含N个空白分隔的整数, A[i], 表示第i_个劫匪需要在主展厅的时间。

输出格式 
对每组数据如果有满足条件的方案,输出YES,否则输出 NO

约束条件 
1 <= T <= 20 
1 <= N <= 100 
0 <= G <= 1000000 (106) 
0 <= A[i] <= 100

思路:最开始以为满足需要时间长的就可以了,所以用贪心试了一下,优先为需要时间多的安排,如下


def indianJob(g, a):
    s1=s2=g
    a.sort(reverse=True)
    for i in a:
        if s1>=s2:
            s1-=i
        else:
            s2-=i
        if s1<0 or s2<0: return 'NO'
    return 'YES'


if __name__ == '__main__':
    t = int(input())
    for t_itr in range(t):
        ng = input().split()
        n = int(ng[0])
        g = int(ng[1])
        arr = list(map(int, input().rstrip().split()))
        print(indianJob(g,arr))

WA,因为你只考虑了大的,会导致最后2个数s1,s2很分散,比如:g = 20, n= 5, [10,10,8,8,4]

所以正解是:背包问题,背包容量为g,看能不能装到sum/2


def indianJob(g, a):
    s=sum(a)
    dp=[0]*(g+1)
    for i in a:
        for j in range(g,-1,-1):
            if j>=i: dp[j]=max(dp[j],i+dp[j-i])
#    print(dp)
    t=s//2+1 if s%2 else s//2
    return 'YES' if dp[g]>=t else 'NO'


if __name__ == '__main__':
    t = int(input())
    for t_itr in range(t):
        ng = input().split()
        n = int(ng[0])
        g = int(ng[1])
        arr = list(map(int, input().rstrip().split()))
        print(indianJob(g,arr))

猜你喜欢

转载自blog.csdn.net/zjucor/article/details/82689167
job