蓝桥省一优题详解——热身题(三国游戏、松散子序列)

(1/2)三国游戏

a. 问题重述

X、Y、Z三个数都会经历不同程度的【增加】,问最多多少次【增加】才能使最大数大于其他两数之和。

b. 题型分析

结束条件是:让其中一个数变得相较其他两者之和都大;

为了达到这个条件,我们引入一个概念叫【贡献度】,即相对增长量(X的【贡献度】 = A-B-C)

所以能够达到结束条件的小条件是:其中一个数的贡献度尽可能大。

换言之,

这是一道经典的贪心类题目:

局部最优(贡献度尽可能大) -->> 全局最优(对应数最后比其他和更大)

而且这个推导关系似乎找不出反对的点,所以可以把这道题就看做贪心的题目来写!

c. 代码实现

# 输入元素
n = int(input())
A = list(map(int,input().split()))
B = list(map(int,input().split()))
C = list(map(int,input().split()))

def win(A,B,C):# 以A元素获胜为例
    w = 0 #结束条件记录
    contribute = [] # 每个时间对获胜的献祭值
    for i in range(n):
        contribute.append(A[i]-B[i]-C[i])

    contribute.sort(reverse = True) # 贡献最多的事件先发生(局部最优思想)
    for i in range(n):
        w += contribute[i]

        if w <= 0: # 只有w大于0的情况才符合题意
            return (i) # 第i个使得小于0了,说明i-1还是大于零的,但是由于range是从0开始遍历的,故返回i就行
    return n # 都不小于零说明n遍历完了

# 调用函数
result = max(win(A,B,C),win(B,C,A),win(C,B,A))

# 特殊情况
if result == 0:
    print(-1)
else:
    print(result)
    

(2/2)松散子序列

a. 问题重述

意思就是你要至少隔一个数取值,问取到的最大价值(a价值为1,z价值26)

举个例子,假如给的字符串是‘abcde’:

不能连续取,则最大取作“a”、“c”、“e”(第一个、第三个、第五个)

b. 题型分析

这是经典的打家劫舍类型题目(也是隔间偷钱,问偷得的最大价值),而打家劫舍问题是动态规划(Dynamic Programming)能解决的经典题目。

图1 动态规划能解决的题型 

对于动态规划类型题目的解题思路,读者若是想有一个全面的把握我推荐去b站搜索“代码随想录”的动态规划部分,以下的分析思路也是按照模版所著。

对于动态规划的解题有五个步骤:

  1. 明确dp数组的定义
  2. 确定递推公式
  3. dp数组的初始化
  4. 了解遍历顺序
  5. 如有报错可通过打印dp数组来检查

对于本题我们按照上面的思路分析之:

  1. 一般都是问什么设什么,本题求的是最大价值,故有下标为“ i ”时的最大价值是“ dp[i] ”,请随时记住 dp[i] 的含义
  2. 因为是隔数取值,所以 dp[i] 只有两种情况:假如现在有3个数,要么取第一和第三个数,要么取第二个数。
    dp[i] = max(value[i]+dp[i-2],dp[i-1])
  3. dp数组的初始化,因为取得是最大值,故初始化为0没有问题
  4. 从前往后取
  5. .. 

c. 代码实现

# 字母转化为价值
def value(a):
    return (ord(a)-96)

s = input()
# def + initiatize(初始化)
dp = [0] * (len(s)+1) # 多一个0防止越界

# sequence(遍历顺序) and formula(递推公式)
for i in range(len(s)):
    dp[i] += max(dp[i-1],dp[i-2] + value(s[i]))

print(max(dp))

持续更新,评论区交流

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值