5194

https://www.luogu.com.cn/problem/P5194

P5194 [USACO05DEC] Scales S

题目描述

约翰有一架用来称牛的体重的天平。与之配套的是 N \ ( 1 \leq N \leq 1000 ) 个已知质量的砝码(所有砝码质量的数值都在 32 位带符号整数范围内)。

每次称牛时,他都把某头奶牛安置在天平的某一边,然后往天平另一边加砝码,直到天平平衡,于是此时砝码的总质量就是牛的质量(约翰不能把砝码放到奶牛的那边,因为奶牛不喜欢称体重,每当约翰把砝码放到她的蹄子底下,她就会尝试把砝码踢到约翰脸上)。

天平能承受的物体的质量不是无限的,当天平某一边物体的质量大于C \ ( 1 \leq C \leq 2^{30} ) 时,天平就会被损坏。砝码按照它们质量的大小被排成一行。并且,这一行中从第 3 个砝码开始,每个砝码的质量至少等于前面两个砝码(也就是质量比它小的砝码中质量最大的两个)的质量的和。

约翰想知道,用他所拥有的这些砝码以及这架天平,能称出的质量最大是多少。由于天平的最大承重能力为 C,他不能把所有砝码都放到天平上。

现在约翰告诉你每个砝码的质量,以及天平能承受的最大质量,你的任务是选出一些砝码,使它们的质量和在不压坏天平的前提下是所有组合中最大的。

输入格式

1 行输入两个用空格隔开的正整数 N  和  C

2  N+1 行:每一行仅包含一个正整数,即某个砝码的质量。保证这些砝码的质量是一个不下降序列。

输出格式

输出一个正整数,表示用所给的砝码能称出的不压坏天平的最大质量。

输入输出样例 #1

输入 #1

3 15
1
10
20

输出 #1

11

代码:

import sys
input=sys.stdin.readline
fama=[0]
list1=[0]
n,c=map(int,input().split())
max_num=0
def dfs(cur,index):
    global max_num,c
    if cur+list1[index]<=max_num:
        return 
    max_num=max(cur,max_num)

    if index==0:
        return
    if cur+fama[index]<=c:
        dfs(cur+fama[index],index-1)
    dfs(cur,index-1)
i=1
while(i<=n):
    m=int(input())
    fama.append(m)
    if fama[i]>c:
        break

    list1.append(list1[i-1]+fama[i])
    i+=1
    
dfs(0,i-1)
print(max_num)

题解:

这道题是DFS和剪枝,通过学习别人的代码,总算明白了DFS和剪枝

这道题是斐波拉期数列,所以数据最多只有30. 最普通的算法应该是230 次运算

但可以通过剪枝去除无效的情况,上述剪枝有3个

if cur+list1[index]<=max_num:
    return 

1.list1为前缀和 当cur+list1[index]小于等于max_num,则不需要再往前遍历

if fama[i]>c:
    break

2.当单个砝码大于c,则后续砝码都无效

if cur+fama[index]<=c:
    dfs(cur+fama[index],index-1)
dfs(cur,index-1)

3.当 cur+fama[index]大于c,则跳过当前砝码

另外这行代码‘dfs(cur,index-1)’ 不仅处理了 ‘当 cur+fama[index]大于c,则跳过当前砝码 ’ 的情况

也处理了当 ‘dfs(cur+fama[index],index-1)’函数结束时的情况,相当于是处理完左子树,再处理右子树,而左子树是取fama[index],右子树是不取fama[index],而取fama[index-1],这样把每种情况都考虑到了,从而找到最优解。

全部评论
点赞 回复 分享
发布于 12-24 21:03 江西

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务