牛客周赛40 记录

没赶上比赛,vp了一下,CD两题思路都是对了的,但是优化的不好,而且vp中间放学了,补一下题,可惜,本来想上个分的

C-小红的排列构造_构造

对于数组a中的每个a_i,若其不等于p_i中,则必等于q_i,要满足数组p和q是[1,n]的排列,所以需要对要添加到p或q中的a_i做重复判断,最后按照顺序把p和q中没出现的数字分别加入其中。

最后对于数组中空值的填充设置两个指针分别遍历两个标记数组。

不知道为什么刚开始数组里直接存的元素超时了,然后就给误导了,最后改成存下标过了,可能是列表的pop 和 index 太慢了吧

n = int(input())
li = list(map(int, input().split()))
a1 = [0] * n
a2 = [0] * n
fa1 = [1 for i in range(n + 2)]
fa2 = [1 for i in range(n + 2)]
f = 1
for i in range(n):
    if fa1[li[i]] == 1:
        a1[i] = li[i]
        fa1[li[i]] = 0
    elif fa2[li[i]] == 1:
        a2[i] = li[i]
        fa2[li[i]] = 0
    else:
        f = 0
        break
if f == 0:
    print(-1)
else:
    p1, p2 = 1, 1
    for i in range(n):
        if a1[i] == 0:
            while fa1[p1] == 0:
                p1 += 1
            fa1[p1] = 0
            a1[i] = p1
        elif a2[i] == 0:
            while fa2[p2] == 0:
                p2 += 1
            fa2[p2] = 0
            a2[i] = p2
    print(*a1)
    print(*a2)

D-小红升装备_多重背包

多重背包的变式,把升级上限看作每种物品的最大数量,最初选择时价值为初始战力

刚开始TLE了,以为要二进制拆分,后来发现状态转移的while循环可以优化一下,如果现在的金币已经不足以再升级这个装备了,没必要判断到这个装备的升级上限了

还是对dp的理解比较肤浅,这里应该是还能用滚动数组一维优化的

n, m = map(int, input().split())
li = []
for i in range(n):
    li.append(list(map(int, input().split())))
dp = [[0] * (m + 3) for i in range(n + 3)]
for i in range(1, n + 1):
    for j in range(m + 1):
        dp[i][j] = dp[i - 1][j]
        w = i - 1
        k = 0
        while k <= li[w][-1] and j >= li[w][1] + li[w][2] * k:
            dp[i][j] = max(dp[i - 1][j - (li[w][1] + li[w][2] * k)] + li[w][0] + k * li[w][-2], dp[i][j])
            k += 1
print(dp[n][m])

E-小红的矩阵划分_思维、贪心

考虑一下两种形状各方块的平均价值, L形自然是x/3 , 正方形为 y/4,优先选择平均价值大的。

对于可能出现的余数做判断

虽然没有严格的证明,而且我也没有很好的思维😭😭😭TT

n,x,y = map(int,input().split())
S = n * n
if x * 4 < y * 3:
    # 先选正方形
    cnt = S // 4
    ans = cnt * y
    if S - cnt * 4 >= 3:
        ans += x
else:
    cnt = S // 6
    ans = cnt * x * 2
    if S - cnt * 6 >= 4:
        ans += y
print(ans)

F貌似是个概率题,后面再补罢!

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值