这是著名的意大利抢劫——“偷天换日”的印度版本. 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))