Acwing 区间DP 计数类DP

news2024/11/27 16:52:16

1.区间DP

Acwing 282.石子合并
在这里插入图片描述
思路分析:
在这里插入图片描述

  • f(i,j)表示将第i堆石子到第j堆石子合并为一堆时的最小代价;
  • 状态划分:选一个分割点k,将[i-k]和[k+1,j]这两个区间的石子合并,然后加上两个区间的合并总代价(采用前缀和计算区间i到j的值,s[j]-s[i-1]😉
  • 初始从枚举区间长度开始(即石子堆数),区间长度len从2到n枚举(从2开始是因为,若len为1,则没必要合并)
  • 然后枚举左端点i,从l到i+len-1;
  • k从左端点i开始枚举,比如k=i+1时,区间被分割为(i,i+1),(i+2,i+len-1),左边区间就一堆,右边区间len-1堆;
  • 状态转移方程:f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]+s[r]-s[l-1])

具体实现代码(详解版):

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 310; 
int n; 
int s[N]; // 用于存储石子堆的大小,以及后续的前缀和
int f[N][N]; // 动态规划数组,f[l][r] 表示合并从第 l 堆到第 r 堆石子的最小代价

int main() {
    cin >> n; 

    
    for (int i = 1; i <= n; i++) {
        cin >> s[i];
    }

    // 计算前缀和数组
    // s[i] 表示从第1堆石子到第i堆石子的总和,用于快速计算区间内石子总和
    for (int i = 1; i <= n; i++) {
        s[i] += s[i - 1];
    }

    // 枚举区间长度 len,从2开始,因为长度为1的区间不需要合并
    for (int len = 2; len <= n; len++) {
        // 枚举区间的左端点 i,右端点 r = i + len - 1
        for (int i = 1; i + len - 1 <= n; i++) {
            int l = i, r = i + len - 1; // l 是左端点,r 是右端点

            // 初始化 f[l][r] 为一个很大的值,确保后面计算的最小值能够替换它
            f[l][r] = 1e8;

            // 枚举分割点 k,将区间 [l, r] 分成 [l, k] 和 [k+1, r] 两部分
            for (int k = l; k < r; k++) {
                // 动态规划转移方程:
                // 合并 [l, k] 和 [k+1, r] 的代价加上合并整个区间的代价
                f[l][r] = min(f[l][r], f[l][k] + f[k + 1][r] + s[r] - s[l - 1]);
            }
        }
    }

    // 输出从第1堆到第n堆的最小合并代价,即 f[1][n]
    cout << f[1][n] << endl;

    return 0;
}

2.计数类DP

Acwing 900.整数划分
在这里插入图片描述
实现思路:本题求的是方案个数,而不要求方案顺序,即4=1+1+2 和4=1+2+1是一样的
(1)方案一:转化为完全背包问题。将n看成是背包容量,而1~n之间的数看成物品,且各个物品的数量是无限的,至此转化为完全背包问题
在这里插入图片描述

  • f(i,j)表示从前i个数字(物品)中选择,之和恰好是j(体积)的方案个数
  • 以第i个数字选择了几次(物品i放了几个)做集合划分。若只选0个i,那么前i-1数的选择之和已经满足j,故为f[i-1][j];若第i个数字选择了k次,那么前i-1个数的选择之和为j-k*v[i],故f[i-1][j-v[i]]
  • 类似完全背包问题的分析与优化:

f[i][j] = f[i - 1][j] + f[i - 1][j - i] + f[i - 1][j - 2i] + .... + f[i - 1][j - k*i]

f[i][j - i] = f[i - 1][j - i] + f[i - 1][j - 2i] + .... + f[i - 1][j - k*i]

  • 所以:

状态转移方程f[i][j] = f[i - 1][j] + f[i][j - i]

优化至一维

f[j] = f[j] + f[j - i]表示和为j的方案数量

具体实现代码(详解版):

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010, mod = 1e9 + 7; 
int n; 
int f[N]; // 动态规划数组 f[j] 表示将整数 j 拆分为若干正整数之和的方案数

int main() {
    cin >> n; 

    f[0] = 1; // 初始化 f[0] = 1,因为将0拆分为零个数只有一种方案(空方案)

    // 遍历所有正整数 i,表示我们将 i 作为拆分的一部分
    for (int i = 1; i <= n; i++) {
        // 遍历所有从 i 到 n 的数 j,更新将 j 拆分的方案数
        for (int j = i; j <= n; j++) {
            //转移方程
            f[j] = (f[j] + f[j - i]) % mod;
        }
    }

    cout << f[n] << endl;

    return 0;
}

(2)方案二
在这里插入图片描述

  • f[i][j]表示,所有总和是i,并且恰好表示成j个数之和的方案的数量。
  • 集合划分,能够分为如下两类:
    • 方案中最小值是1的所有方案,这时候去掉一个1,此时和变成了i - 1 ,个数变成了j - 1 ,即f[i - 1][j - 1];
    • 方案中最小值大于1的所有方案,此时将j个数都减去1,此时和变成了i - j(j个数每个数都-1,共-j),个数还是j,即f[i - j][j];
  • 最终状态转移方程为:f[i][j] = f[i - 1][j-1] + f[i-j][j];
  • 结果输出应为f[n][1] + f[n][2] + f[n][3] + … + f[n][n]

具体实现代码(详解版):

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010, mod = 1e9 + 7; 
int n; 
int f[N][N]; 

int main() {
    cin >> n; 
    
    f[0][0] = 1;//和为0,表示的方案为1
    
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= i ; j ++){
            //两种情况:1.最小值是1;2.最小值大于1.
            f[i][j] = (f[i - 1][j - 1] + f[i - j][j]) % mod;
        }
    }
    
    int res = 0;
    //f[n][1]+f[n][2]+...+f[n][n]
    for(int i = 1; i <= n; i ++) res =(res + f[n][i]) % mod;
    
    cout << res << endl;

    return 0;
}

以上就是区间DP和计数类DP的问题,分析方法还是和之前的一样,重点在于问题的转化和状态转移方程的求解~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2192648.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在线Xpath匹配定位测试工具

具体请前往&#xff1a;在线Xpath-匹配-定位-调试/测试工具

速速收藏!这些2024年上映的AI电影与短剧,申请加入你的国庆假期宅家计划!

2024年上映的AI电影 01 科幻惊悚电影《致命AI Afraid》 导演&#xff1a;克里斯韦兹上映日期:2024-08-30(美国)片长:84分钟剧情简介&#xff1a;Curtis一家被选中去测试一种革新性的居家设备&#xff1a;数字家庭助手AIA&#xff0c;包括各种感应设备和摄像头等&#xff0c;…

【2024】前端学习笔记13-JavaScript修改网页样式

学习笔记 1.修改网页样式1.1.修改内联样式(`style`属性)1.2.使用`cssText`属性:2.修改样式类(`classList`属性)2.1.添加和移除类名2.2.切换类名(`toggle`方法)1.修改网页样式 1.1.修改内联样式(style属性) 直接修改元素的style属性: 可以通过获取元素对象,然后直…

java计算机毕设课设—推箱子游戏(附源码、文章、相关截图、部署视频)

这是什么系统&#xff1f; 基于JAVA的推箱子游戏是一个经典的益智游戏&#xff0c;旨在通过推动箱子到指定位置来锻炼玩家的思维和策略能力。本游戏提供了多种不同难度的关卡&#xff0c;以满足不同玩家的需求。整个程序包括五个主要模块&#xff1a;初始化模块、画图模块、移…

Dart 高级语法

Dart 是一种由 Google 开发的开源编程语言&#xff0c;旨在为构建高性能、可移植的应用程序提供支持。它被设计用于多种平台&#xff0c;包括Web、移动设备&#xff08;通过 Flutter 框架&#xff09;、服务器端应用以及桌面应用。以下是一些 Dart 中比较高级的语言特性和模式。…

Ambari搭建Hadoop集群 — — 问题总结

Ambari搭建Hadoop集群 — — 问题总结 一、部署教程&#xff1a; 参考链接&#xff1a;基于Ambari搭建大数据分析平台-CSDN博客 二、问题总结&#xff1a; 1. VMwear Workstation 查看网关 2. 资源分配 参考&#xff1a; 硬盘&#xff1a;master&#xff08;29 GB&#xff…

连续时间傅里叶变换

一、非周期信号的表示&#xff1a;连续时间傅里叶变换 傅里叶变换对&#xff1a; 通常称为的频谱 二、傅里叶变换的收敛 1、绝对可积 2、在任何有限区间内&#xff0c;只有有限个最大值和最小值 3、在任何有限区间内&#xff0c;有有限个不连续点&#xff0c;且在每个不连…

C语言动态内存管理(26)

文章目录 前言一、引子二、malloc三、calloc四、realloc五、free六、常见的动态内存错误对NULL指针进行解引用操作对动态开辟空间的越界访问对非动态开辟的内存使用free释放使用free释放动态开辟内存的一部分对同一块内存多次释放动态开辟内存忘记释放&#xff08;内存泄漏&…

k8s 之安装helm服务

helm安装包下载helm官网_zh 作者&#xff1a;程序那点事儿 日期&#xff1a;2024/01/30 00:51 下载安装包 wget https://get.helm.sh/helm-v3.2.3-linux-amd64.tar.gz 解压安装包 tar -zxcf helm-v3.2.3-linux-amd64.tar.gz 进入到解压目录 cd linux-amd64 将helm目录拷贝…

101. 对称二叉树【 力扣(LeetCode) 】

文章目录 零、原题链接一、题目描述二、测试用例三、解题思路3.1 递归3.2 迭代 四、参考代码4.1 递归4.2 迭代 零、原题链接 101. 对称二叉树 一、题目描述 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 进阶&#xff1a;你可以运用递归和迭代两种方法解决…

YOLO11改进|注意力机制篇|引入上下文锚注意力机制CAA

目录 一、【CAA】注意力机制1.1【CAA】注意力介绍1.2【CAA】核心代码 二、添加【CAA】注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【CAA】注意力机制 1.1【CAA】注意力介绍 CAA注意力机制的结构图如下&#xff0c;下面根据…

Selenium WebDriver和Chrome对照表

PS&#xff1a;我的没下载WebDriver 也没配置环境变量 也能用Selenium 网上有说把WebDriver放到chrome的安装目录并将路径配到path中【可能之前用playwright下载过】 查看浏览器版本号 在浏览器的地址栏&#xff0c;输入chrome://version/&#xff0c;回车后即可查看到对应版…

Java项目实战II基于Java+Spring Boot+MySQL的智能推荐的卫生健康系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者 一、前言 在健康意识日益增强的今天&#xff0c;如何为用户提供个性化、精准的卫生健康建议成为了一个亟待解决…

java中的多层循环控制,包括金字塔和九九乘法表的打印

多重循环控制 多重循环控制练习 多重循环控制 1.将一个循环放在另一个循环体内&#xff0c;就形成了嵌套循环。其中&#xff0c;for&#xff0c;while&#xff0c;do…while均可以作为外层循环和内层循环。【建议一般用两层&#xff0c;最多不要超过3层&#xff0c;否则代码的…

【前端】前端数据转化为后端数据

【前端】前端数据转化为后端数据 写在最前面格式化数组代码解释hasOwnProperty是什么&#xff1f; &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&#xff0c;挖掘无限…

k8s实战-3

k8s实战-3 一、Ingress1.安装2.测试 二、存储抽象1.环境准备2.PV和PVC3.ConfigMap4.Secret 总结 一、Ingress Ingress 类似于一个“网关”&#xff0c;它负责将外部 HTTP 请求路由到集群内的服务。你可以把它想象成一个“交通警察”&#xff0c;根据请求的 URL 和路径&#xf…

无锡自闭症康复寄宿学校:每天的康复方式揭秘

无锡自闭症康复寄宿学校的启示&#xff1a;揭秘广州星贝育园的日常康复方式 在自闭症儿童的教育与康复领域&#xff0c;每一所学校都在用自己的方式探索着前行的道路。无锡的自闭症康复寄宿学校以其独特的康复方式和显著的效果&#xff0c;为众多家庭带来了希望。而在广州&…

jvisualvm学习

系列文章目录 JavaSE基础知识、数据类型学习万年历项目代码逻辑训练习题代码逻辑训练习题方法、数组学习图书管理系统项目面向对象编程&#xff1a;封装、继承、多态学习封装继承多态习题常用类、包装类、异常处理机制学习集合学习IO流、多线程学习仓库管理系统JavaSE项目员工…

前端工程化 - Vue

环境准备 Vue-cli是Vue官方提供的一个脚手架&#xff0c;用户快速生成一个Vue的项目模板。 Vue-cli提供了如下功能&#xff1a; 统一的目录结构本地调试热部署单元测试集成打包上线 需要安装Node.js 安装Vue-cli npm install -g vue/cli通过vue --version指令查看是否安装成…

蓝桥杯省赛真题打卡day4

[蓝桥杯 2013 省 A] 大臣的旅费 题目描述 很久以前&#xff0c;T 王国空前繁荣。为了更好地管理国家&#xff0c;王国修建了大量的快速路&#xff0c;用于连接首都和王国内的各大城市。 为节省经费&#xff0c;T 国的大臣们经过思考&#xff0c;制定了一套优秀的修建方案&am…