【Leetcode】1449. Form Largest Integer With Digits That Add up to Target

题目地址:

https://leetcode.com/problems/form-largest-integer-with-digits-that-add-up-to-target/

考虑 1 ∼ 9 1\sim 9 19 9 9 9个数字,给定每个数字的代价,和一个总代价 t t t,问恰好用尽 t t t的情况下,能组成的最大数字是多少。如果无解则返回 0 0 0

能组成的数字一定是正整数,所以位数越多越大。在位数最大的情况下,字典序越大数字越大。所以问题就变为,恰好用完 t t t的代价,最多能得到几位数,在位数最多的情况下,字典序最大可以得到多少。同一个数字允许用多次,从而本质上是个完全背包问题。设 f [ k ] [ s ] f[k][s] f[k][s]是只考虑 1 ∼ k 1\sim k 1k,且总代价恰好为 s s s的情况下能取得的最大位数,则可以按照 k k k取不取来分类,所以: f [ k ] [ s ] = max ⁡ { f [ k − 1 ] [ s ] , f [ k ] [ s − c [ k ] ] + 1 } f[k][s]=\max\{f[k-1][s],f[k][s-c[k]]+1\} f[k][s]=max{f[k1][s],f[k][sc[k]]+1} c [ k ] c[k] c[k] k k k的代价。推完 f f f之后,从后向前推,对于 f [ k ] [ s ] f[k][s] f[k][s],如果 f [ k − 1 ] [ s ] > f [ k ] [ s − c [ k ] ] + 1 f[k-1][s]>f[k][s-c[k]]+1 f[k1][s]>f[k][sc[k]]+1,那么 k k k是不能取的,否则由于要字典序更大,要取 k k k。代码如下:

class Solution {
 public:
  string largestNumber(vector<int>& cost, int target) {
    int f[10][target + 1];
    memset(f, -1, sizeof f);
    f[0][0] = 0;
    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 - cost[i - 1]]) 
          f[i][j] = max(f[i][j], f[i][j - cost[i - 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;
  }
};

时空复杂度 O ( t ) O(t) O(t)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值