[H背包] lc1449. 数位成本和为目标值的最大数字(背包求具体方案+状态定义+边界情况)

Posted Ypuyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[H背包] lc1449. 数位成本和为目标值的最大数字(背包求具体方案+状态定义+边界情况)相关的知识,希望对你有一定的参考价值。

1. 题目来源

链接:1449. 数位成本和为目标值的最大数字

相关:

2. 题目解析

完全背包求具体方案的问题,是 [01背包] 背包问题求具体方案(01背包+求方案数+思维) 的变种。


首先如果要使满足要求的拼的数最大,有两个要求:

  • 位数尽量大
  • 位数相同,字典序最大

有限制的组合问题求最优解,一般会对应到背包问题。 在此就是从 1~9 中选,要求花费总和等于 target,让拼出来的数最大。

抽象为背包问题,背包容量为 target,9 个物品,物品体积为 cost[i],物品价值为 1。

故问题转化为,给定 9 个物品,一个背包,求在恰好装满背包的情况下,总价值最大的所有方案中字典序最大的一个方案。 至此,已经完全转化为 [01背包] 背包问题求具体方案(01背包+求方案数+思维)

但是,背包问题中细节很多,背包恰好装满、至多装满、物品次数限制等。在循环、初始化方面有所不同。

完全背包、01 背包的状态转移方程对比:

f[i][j] 表示前 i 个物品恰好装 j 体积的最大价值
完全背包:f[i][j]=max(f[i-1][j], f[i][j-cost[i]]+1);
01背包:f[i][j]=max(f[i-1][j], f[i-1][j-cost[i]]+1);

这样就能求出最大价值,即最大的位数。求方案就是倒推一遍即可,这个方案就是字典序最大的方案,即要求我们尽可能选 9,如果不能选 9 再选 8,同理往后选即可。

答案为 f[9][target],它有两种转移情况:

  • 不选 9,则 f[9][target]=f[8][target]
  • 选 9 则 f[9][target]=f[9][target-cost[9]]+1
  • 即只需要从后往前进行倒推即可,当选 9 和不选 9 都一样时,我们要将 9 选上,保证字典序尽量大。

注意本题的初始化方式,本题背包定义是前 i 个物品恰好装满 j 体积的最大价值,故当一个物品都没有时,它是没有体积的,无法恰好装满 j 体积,自然没有价值

初始化时,f[0][1~target] 均是非法方案,不能像以往一样直接将其置为 0,而是要将其置为 -INF,视为非法情况。


时间复杂度: O ( n m ) O(nm) O(nm) 物品数量 x 最大容量=9 * 5000

空间复杂度: O ( n m ) O(nm) O(nm)


class Solution {
public:
    string largestNumber(vector<int>& cost, int target) {
        vector<vector<int>> f(10, vector<int>(target + 1));

        // 本题保证恰好装满背包,即 0 物品时,体积一定是 0,体积不为 0 则均是非法情况,赋为最小值即可
        for (int i = 1; i <= target; i ++ ) f[0][i] = -1e8;

        for (int i = 1; i <= 9; i ++ )
            for (int j = 0; j <= target; j ++ ) {
                f[i][j] = f[i - 1][j];
                if (j >= cost[i - 1]) f[i][j] = max(f[i][j], f[i][j - cost[i - 1]] + 1);
            }

        // 无解情况,1 个数都没选
        if (f[9][target] < 1) return "0";
        
        // 倒推求方案,保证字典序最大
        string res;
        for (int i = 9, j = target; i; i -- ) {
            while (j >= cost[i - 1] && f[i][j] == f[i][j - cost[i - 1]] + 1) {
                res += to_string(i);
                j -= cost[i - 1];
            }
        }

        return res;
    }
};

以上是关于[H背包] lc1449. 数位成本和为目标值的最大数字(背包求具体方案+状态定义+边界情况)的主要内容,如果未能解决你的问题,请参考以下文章

1449. 数位成本和为目标值的最大数字

力扣python每日抑题——1449. 数位成本和为目标值的最大数字

LeetCode 1449 数位成本和为目标的最大数字[动态规划] HERODING的LeetCode之路

背包DP(数位成本和为目标值的最大数字+完全平方数+零钱兑换+盈利计划+最后一块石头的重量+目标和+1和0)

leetcode-26双周赛-5399-数位成本和为目标值的最大数字

leetcode-26双周赛-5399-数位成本和为目标值的最大数字