洛谷做题笔记(0)

题目CF1554A:给定序列 an, 且 1<= l < r<=n,最大化 max(al,al+1,…,ar) × min(al,al+1,…,ar)。

//输入输出样例
输入-----------------------------------------------------------
4
3
2 4 3
4
3 2 3 1
2
69 69
6
719313 273225 402638 473783 804745 323328
输出------------------------------------------------------------
12
6
4761
381274500335

分析:
假设我们有两个相邻的数 a,b(a<b),显然对于这个长度为 2 的序列的解是 a⋅b。现在我们向 b 后面添加一个数 c,对于这个序列的解改变当且仅当两种情况:

  • 第一种情况,当 b<c 时,解为 a⋅c。
  • 第二种情况,当 a>c 时,解为 b⋅c。

对于第一种情况,显然b⋅c>a⋅c,所以我们将 a移出序列可以得到更优解;对于第二种情况,显然解与 a 无关。综上,我们只需要考虑序列长度为 2 的情况,因此我们只需要对所有数依次判断更新答案即可。

import sys
input = sys.stdin.realine
for _ in range(int(input())):
    n = int(input())
    l = list(map(int,input().split()))
    ans = 0
    for i in range(n-1):
        ans = max(ans,l[i]*l[i+1])
    print(ans)

参考


P1007:士兵过独木桥的最大撤离时间和最小撤离时间

输入样例:
4(第一行:一个整数 L,表示独木桥的长度。桥上的坐标为1⋯L。1<=L<=5×10³)
2(一个整数N,表示初始时留在桥上的士兵数目0<=N<=5×10³)
1 3(有N 个整数,分别表示每个士兵的初始坐标)
输出样例:
2 4

从正常观察角度时,会发现,调头来调头去是关键,普通模拟根本做不出来!现在,发散一下思维。当你看人当做一群蚂蚁过独木桥时,你根本分不清他是否掉头,既然分不清楚,就干脆不要分开,将两个人作为一个整体,等价于两人穿插而过!你会发现总时间和速度都是一样的!求min考虑最小中的最大值min(a[i],len-a[i]+1);
所以求最大值考虑最大值的最大值!!max(a[i],len-a[i]+1);

n = int(input())
nums = int(input())
max_1 = 0
min_1 = 0
if nums != 0:
    l = list(map(int,input().split())) 一定要先判断nums(N的长度是否为零)之后,再读入列表,否则L读入的可能是空,导致用例不通过
    for i in range(len(l)):
        temp = l[i]
        max_1 = max(max_1,max(temp,n-temp+1))
        min_1 = max(min_1,min(temp,n-temp+1))
    print(min_1,max_1)
else:
    print('0 0')# 一定要考虑nums为零的情况

CF1660C:Get an Even String
给定字符串 s,删除尽可能少的元素使得ai=ai+1且 i为 奇数

要素提取:

  • 给定T组数据,每组数据包括一个字符串s
  • 可删除字串符中任意字母
  • 目标状态:最终字符串的长度是偶数,每个奇数位上的字母和它下一位上的字母相同
  • 求最少需要删去的字母个数

贪心策略:
要使得删除的元素数量尽可能少,从前往后扫一遍,找到相同的就把中间的都删了。这样显然所删除的元素是最少的,比如对于字符串s=abcabcb,不妨设 k表示要删掉的字符数。

  • i=1,只有 a 一个字母,不管。
  • i=2,有 a,b 两个了,但是没有相同的,不管。
  • i=3,有 a,b,c 三个了,但是还是没有相同的,继续。
  • i=4,有两个a,将中间的都删掉,k=2。
  • i=5,有两个a,但是前面处理过这部分了,我们就不管,还有一个 b。
  • i=6,有 b,c 了,没有相同的。
  • i=7,有两个b,删掉 c,k=3。所以答案是3
    动态规划策略:
    dp[i]表示到第i个位置所能匹配的最大不交叉对子数,然后用字符串的长度减去到最后一个位置的最大不交叉对子数,就是删掉元素的最少数量。
# 贪心策略
for _ in range(int(input())):
    l = input().strip()
    s = [] # 初始化一个空列表,用来记录是否出现了匹配的对子
    ans = 0 # 用来记录不被删去的字符数量
    for i in range(len(l)):
        s.append(l[i])
        temp = s.count(l[i])
        if temp == 2: # 判断当前元素是不是出现了两次,判断是否匹配
            s = []
            ans += 2
        
    print(len(l)-ans)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值