背包问题再进化--通过装载路径得答案

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了背包问题再进化--通过装载路径得答案相关的知识,希望对你有一定的参考价值。

题目

在这里插入图片描述

题目解析

看完题目,可能会懵逼,实际就是选择成本和为target的最大数字。
那么为了让它为最大数字,首先要满足的肯定是位数要够多。所以通过背包模板可以求出成本和为target的最大位数(在背包看来就是物品装入的最大次数)

所以根据以上分析做题可以分为两个步骤:

  1. 找出和为target的最多取数次数(对应最大位数),所以通过背包模板可以求出成本和为target的最大位数(在背包看来就是物品装入的最大次数)。
  2. 遍历已经得出结果的dp数组,根据它的路径来判断该位数字是否可以取作数位结果,同时为了保证得到的数位是最大情况,需要让数位从大到小的情况来取。
  3. 对于此题的路径判断方式,如果是直接形式的二维,我们可以通过一个额外的数组来记录每次是否取了物品,若未取则转移到from[i-1][j],若取了则更新答案并转移到from[i][j-coin[i-1]]。二维如果这样用额外的数组表示,明显会很直观,但额外的空间有点难受。实际上还可以直接用原数组转移:
for(int i=9,j=target;i>=1;i--){
            int u = cost[i-1];
 //这里如果不满足判断条件,也就是不取第i个物品,则会自动转移到下一个i-1的状态(毕竟外面这层for循环不是盖的。
  while (j>=u && dp[i][j]==dp[i](若是01背包则为i-1)[j-u]+1){
 //一旦取了第i个物品,则开始更新答案,并判断下一个状态是否还取该物品
                ans += to_string(i);
                j-=u;
            }
        }

优化为一维版本

//由于仅和本行前面的结果相关,即dp[i][j] = dp[i][j-c]故可直接用dp[j-c]代替dp[i][j-c]
for(int i=9,j=target;i>=1;i--){
            int u = cost[i-1];
      //判断该物品是否被取
  while (j>=u && dp[j]==dp[j-u]+1){
 //一旦取了第i个物品,则开始更新答案,并判断下一个状态是否还取该物品
                ans += to_string(i);
                j-=u;
            }
        }
//如果是01背包我暂时没想出如何在这个回顾路径的过程中优化为一维数组,毕竟他得依赖dp[i-1][j],而一维的只能表示dp[i][j]...

解题代码

只放出了最后的一维解题代码哈。。

效率直接双百:
在这里插入图片描述

class Solution {
public:
    string largestNumber(vector<int>& cost, int target) {
        int dp[target+1];memset(dp,0xf8,sizeof(dp));
        //base case:
        dp[0] = 0;
        for(int i=1;i<= cost.size();i++){
            for(int j=cost[i-1];j<=target;j++){
                //防止不能拼凑的也被继续拼凑
                if(dp[j-cost[i-1]]<0)
                    continue;
                dp[j] = max(dp[j],dp[j-cost[i-1]]+1);
            }
        }
        if(dp[target]==0xf8f8f8f8)return "0";
        //开始顺着得到最终结果的路径选择相应的答案
         string ans = "";
        for (int i = 9, j = target; i >= 1; i--) {
            int u = cost[i - 1];
            //优先选择数字大的cost[8]开始,以便得到最大值的路径
            while (j >= u && dp[j] == dp[j - u] + 1) {
                ans += '0'+i;
                j -= u;
            }
        }
        return ans;
    }
};

以上是关于背包问题再进化--通过装载路径得答案的主要内容,如果未能解决你的问题,请参考以下文章

GPT-3再进化:通过浏览网页来提高事实准确率

单调队列优化多重背包

装载问题,0-1背包

动态规划之01背包问题(含代码C)

0-1背包-回溯法

Re0:DP学习之路 01背包如何打印路径?