多维dp-数组多维压缩到一维

本文介绍了使用Python实现的乌龟棋代码,涉及四重for循环和idx函数。第一题是计算给定数组的最优路径,第二题则是在成本限制下找到满足条件的最小成本。通过动态规划方法解决高维数组问题。
摘要由CSDN通过智能技术生成

题目列表

乌龟棋代码。四重for循环。主要是idx函数。
经过测试。1e6的数组在pypy3里面大概是20MB左右,还是不会MLE的。

import sys

# sys.stdin = open('./../../input.txt', 'r')
I = lambda: int(input())
MI = lambda: map(int, input().split())
LI = lambda: list(map(int, input().split()))

n, m = MI()
a = LI()
c = LI()
cc = [0] * 4
for x in c: cc[x - 1] += 1
D1, D2, D3, D4 = (x + 1 for x in cc)

idx = lambda x1, x2, x3, x4: x1 + x2 * D1 + x3 * D1 * D2 + x4 * D1 * D2 * D3
N = D1 * D2 * D3 * D4
dp = [0] * N
dp[0] = a[0]
for i in range(D1):
    for j in range(D2):
        for k in range(D3):
            for l in range(D4):
                d = i + j * 2 + k * 3 + l * 4
                if i != 0:
                    dp[idx(i, j, k, l)] = max(dp[idx(i, j, k, l)], dp[(idx(i - 1, j, k, l))] + a[d])
                if j != 0:
                    dp[idx(i, j, k, l)] = max(dp[idx(i, j, k, l)], dp[(idx(i, j - 1, k, l))] + a[d])
                if k != 0:
                    dp[idx(i, j, k, l)] = max(dp[idx(i, j, k, l)], dp[(idx(i, j, k - 1, l))] + a[d])
                if l != 0:
                    dp[idx(i, j, k, l)] = max(dp[idx(i, j, k, l)], dp[(idx(i, j, k, l - 1))] + a[d])

# print(dp)
print(dp[-1])

第二题,达到指定参数且成本最小。本题使用的字典和元组来访问高维数组。
数据范围是6**5*10左右。

import sys

sys.stdin = open('./../../input.txt', 'r')
I = lambda: int(input())
MI = lambda: map(int, input().split())
LI = lambda: list(map(int, input().split()))

n, K, P = MI()

mtx = [LI() for _ in range(n)]

dp = dict()
dp[tuple([0] * K)] = 0
for i in range(n):
    cost = mtx[i][0]
    xs = mtx[i][1:]
    ndp = dict()
    for k, v in dp.items():
        nk = [0] * K
        for i in range(K):
            nk[i] = min(k[i] + xs[i], P)
        nk = tuple(nk)
        if nk in ndp:
            ndp[nk] = min(dp[k] + cost, ndp[nk])
        else:
            ndp[nk] = dp[k] + cost

    for k, v in ndp.items():
        if k in dp:
            dp[k] = min(dp[k], v)
        else:
            dp[k] = v

ans = float('inf')
for k, v in dp.items():
    if all(k[i] >= P for i in range(K)):
        ans = min(ans, dp[k])

print(ans if ans < float('inf') else -1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值