当前位置: 首页 > news >正文

状态机dp

 

lc3748
 
1. 确定DP状态
 
- 定义  f[i][0] :以  nums[i]  结尾、不删除元素的最长非递减子数组长度;
- 定义  f[i][1] :以  nums[i]  结尾、删除过一次元素的最长非递减子数组长度。
 
2. 确定状态转移方程
 
- 若  nums[i-1] <= nums[i] (连续非递减): f[i][0] = f[i-1][0[i1 , f[i][1] = f[i-1][1[i1 ;
- 若  nums[i-1] > nums[i] (断开): f[i][0] = 1 (重新开始);
- 若  i≥2  且  nums[i-2] <= nums[i] (删中间  nums[i-1]  能衔接): f[i][1] = max(f[i][1], f[i-2][0[i2) ;
- 否则(删后仅含  nums[i-1]  和  nums[i] ): f[i][1] = max(f[i][1], 2) 。
 
3. 初始化DP数组
 
-  f[0] = {1, 1} :单个元素,不删/删(删后无效仍按1算)长度均为1;
-  ans = 1 :初始最大值为第一个元素的长度。
 
4. 确定遍历顺序
 
- 从  i=1  到  n-1  正序遍历:需用到前一个( i-1 )和前两个( i-2 )状态。
 
5. 确定最终结果
 
- 遍历中持续更新  ans ,取“前一个不删+当前(删前一个)”和“当前删一次”的最大值,最终返回  ans 

class Solution {
public:
    int longestSubarray(vector<int>& nums) {
        int n = nums.size();
        vector<array<int, 2>> f(n);
        f[0] = {1, 1};

        int ans = 1; // 以 nums[0] 结尾的子数组长度
        for (int i = 1; i < n; i++) {
            if (nums[i - 1] <= nums[i]) {
                f[i][0] = f[i - 1][0] + 1;
                f[i][1] = f[i - 1][1] + 1;
            } else {
                f[i][0] = 1;
                // 不需要写 f[i][1] = 1,因为下面算出来的值至少是 2
            }

            if (i >= 2 && nums[i - 2] <= nums[i]) {
                f[i][1] = max(f[i][1], f[i - 2][0] + 2);
            } else {
                f[i][1] = max(f[i][1], 2);
            }

            // ans = max({ans, f[i - 1][0] + 1, f[i][1]}); 这种写法比下面的慢
            ans = max(ans, max(f[i - 1][0] + 1, f[i][1]));
        }
        return ans;
    }
};

 

 

lc2431

 

1. 确定DP状态

 

- 定义  dp[j][k] :使用  j  张优惠券、花费不超过  k  金额时,能获得的最大美味值。

- 核心逻辑:用“优惠券数量+花费金额”双维度锁定状态,聚焦“选/不选当前物品”的决策。

 

2. 确定状态转移方程

 

对每个物品  i ,分两种选择更新状态(用临时数组  ndp  避免覆盖原状态):

 

- 不使用优惠券买:若  k + price[i] ≤ maxAmount ,则  ndp[j][k+price[i]] = max(原价值, dp[j][k] + tastiness[i]) ;

- 使用优惠券买:若  j < maxCoupons  且  k + price[i]/2 ≤ maxAmount ,则  ndp[j+1][k+price[i]/2] = max(原价值, dp[j][k] + tastiness[i]) ;

- 不买当前物品: ndp  继承  dp  原有值(默认逻辑,无需额外代码)。

 

3. 初始化DP数组

 

-  dp  为  (maxCoupons+1)×(maxAmount+1)  的二维数组,初始值全为0:未用优惠券、未花费金额时,美味值为0。

 

4. 确定遍历顺序

 

- 外层正序遍历每个物品  i (0到n-1):逐个考虑是否纳入选择;

- 内层先遍历优惠券数  j (0到maxCoupons),再遍历金额  k (0到maxAmount):基于历史状态更新新状态,避免重复计算。

 

5. 确定最终结果

 

- 遍历整个  dp  数组,取所有  dp[j][k] (0≤j≤maxCoupons,0≤k≤maxAmount)的最大值,即为最大美味值

class Solution {

public:

    int maxTastiness(vector<int>& price, vector<int>& tastiness, int maxAmount, int maxCoupons) {

        int n = price.size();

        vector<vector<int>> dp(maxCoupons+1, vector<int>(maxAmount+1));

        for(int i=0; i<n; ++i){

            vector<vector<int>> ndp(dp.begin(), dp.end());

            for(int j=0; j<maxCoupons+1; ++j){

                for(int k=0; k<maxAmount+1; ++k){

                    if(k + price[i] <= maxAmount){

                        ndp[j][k+price[i]] = max(ndp[j][k+price[i]], dp[j][k]+tastiness[i]);

                    }

                    if(j < maxCoupons and k + price[i]/2 <= maxAmount){

                        ndp[j+1][k + price[i]/2] = max(ndp[j+1][k + price[i]/2], dp[j][k]+tastiness[i]);

                    }   

                }

            }   

            dp = move(ndp);

        }

        int ans = 0;

        for(int j=0; j<maxCoupons+1; ++j){

            for(int k=0; k<maxAmount+1; ++k){

                ans = max(ans, dp[j][k]);

            }

        }

        return ans;

    }

};

 

lc3610

选不选

if (i > 0) {//不选

                    dp[i][j] = dp[i - 1][j];

                }

                // 选

                if (j >= p[i]) 

                    dp[i][j] = min(dp[i][j], dp[i][j - p[i]] + 1);

class Solution {

    vector<int> p;

    void getPrimes(int m) {

        // 线性筛法获取前m个质数

        vector<bool> isPrime(1000, true); // 质数范围足够大

        isPrime[0] = isPrime[1] = false;

        int cnt = 0;

        for (int i = 2; cnt < m; ++i) {

            if (isPrime[i]) {

                p.push_back(i);

                cnt++;

                for (int j = 2 * i; j < 1000; j += i) {

                    isPrime[j] = false;

                }

            }

        }

    }

public:

    int minNumberOfPrimes(int n, int m) {

        getPrimes(m);

        if (p.empty()) return -1; // 没有可用质数,直接返回-1

        

        // dp[i][j]:前i+1个质数组成和为j的最小个数

        vector<vector<long long>> dp(m, vector<long long>(n + 1, n + 1)); // 初始化为n+1(最大不可能超过n)

        for (int i = 0; i < m; ++i) {

            dp[i][0] = 0; // 和为0时需要0个质数

        }

        

        for (int i = 0; i < m; ++i) {

            for (int j = 1; j <= n; ++j) {

                // 不选第i个质数

                if (i > 0) {

                    dp[i][j] = dp[i - 1][j];

                }

                // 选第i个质数(如果j不小于当前质数)

                if (j >= p[i]) {

                    dp[i][j] = min(dp[i][j], dp[i][j - p[i]] + 1);

                }

            }

        }

        

        int result = dp[m - 1][n];

        return result > n ? -1 : result;

    }

};

一维

int minNumberOfPrimes(int n, int m) {
        getPrimes(m);
        if (p.size() < m) return -1; // 无法获取m个质数,直接返回-1
        
        // dp[j]:组成和为j时所需的最小质数个数(空间优化,一维DP)
        vector<int> dp(n + 1, n + 1); 
        dp[0] = 0; // 和为0时需要0个质数
        
        for (int prime : p) {
            for (int j = prime; j <= n; ++j) {
                dp[j] = min(dp[j],dp[j - prime] + 1);
            }
        }
        
        return dp[n] > n ? -1 : dp[n];
    }
};

 

http://www.dtcms.com/a/587063.html

相关文章:

  • 网站php怎么做装修公司排名榜十大品牌
  • 网站建设公司自适应源码重庆妇科医院排行榜
  • 深度学习实战(基于pytroch)系列(六)softmax回归原理
  • 编辑网站精智wordpress主题
  • MR重建算法的原理与实现
  • 网站建设饱和了吗有哪些网站可以做任务返现
  • 国外科技网站欣赏网站设计 卡片式设计
  • ZArchiver1.0.10 | 提供强大的加密压缩功能,支持AES算法及文件名加密,界面简洁易于操作
  • p5541题解
  • 热门派对游戏:Grab The Mic商标版权维权,250+店涉案被TRO
  • 【LeetCode】105. 从前序与中序遍历序列构造二叉树
  • 杏坛网站制作购物网站订单状态模板
  • seo整站优化多少钱wordpress文章多个分类显示不出来
  • day11鹏哥C语言-操作符(关系,逻辑,条件)
  • 【Spring/SpringBoot】为什么创建Maven项目,而不直接创建SpringBoot项目
  • 【数据结构】单链表及单链表的实现
  • 深圳外贸公司招聘信息关键词网站优化平台
  • 检查部门网站建设商业计划书模板范文
  • Java EE - 线程的状态
  • wordpress图片下一页整站优化系统
  • AlmaLinux 部署 Samba 服务:文件共享快速实现
  • 做网站需要用到什么技术网站会员权限
  • 江西中联建设集团有限公司网站企业网站内容模块
  • 易企秀微网站如何做文字链接WordPress 磁力
  • 扬州市住房和建设局网站网站获取客户信息需要备案吗
  • dedecms做的网站_网站中的图片总是被同一ip恶意点击网站建设管理情况自查报告
  • 维修网站建设wordpress和代码
  • Java 代理模式全解析:静态代理、JDK 动态代理与 CGLIB 代理实战
  • 做免费外贸网站册域名滨州医学院做计算机作业的网站
  • 保山网站建设哪家好校园推广活动策划方案