news 2026/6/23 19:33:25

P1043 [NOIP 2003 普及组] 数字游戏

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
P1043 [NOIP 2003 普及组] 数字游戏

#环形结构\#破环成链\#区间DP

这道题是关于一个环上的区间DP问题,n个数字收尾相连成一个环,我们的任务是把n个数分成m个部分,各个部分内的数相加并对10取模再相乘,最后得到一个k值。要求求出k的最大值和最小值。


前置知识

区间DP

DP问题的变种,一种解决涉及连续区间的最优性问题的有效方法。通过求出所有较小区间的最优解,地推出包含它们的较大区间的最优解,具有动态规划的最优子结构和无效性的特性。

状态转移方程如下

dp[i][j]=min or max(dp[i][j],dp[i][q]opdp[q+1][j])

注意整个动态规划的过程中Len=j-i需要从小到大执行

for(len=2 to N)

for(i = 1 to N - Len + 1)

j = i + len - 1

for(q = i to j - 1)

这道题在这个基础上加了一个因素,就是我们有k​个区间。

状态定义:dp[i][j][k]表示将子序列A[i...j]恰好划分成k个连续子序列所得的最优解。

核心思想:当我们从i开始到j结束,切割点为q,我们需要从i到q的k-1个区间的最优解,推出i到j之间k个区间的最优解。

破环成链

在算法竞赛中,我们会经常遇到环形结构。这类问题会因为首尾相连的特性变得特别复杂。

“破环成链”是一种思维技巧和模板化处理这类问题的预处理方法,目的是将环形结构转化为我们更容易处理的链式(线性)问题。

核心思想:复制一份环上的元素,接到原序列的末尾,形成一个2N的线性序列。

类比:1000米赛跑

一般学校的操场跑道只有400米,当我们需要跑1000米时,可以将操场变成400米的直线跑道,第二圈接到第一圈后面变成800米,第三圈的半圈接到后面变成1000米。

对于这道题我们只需要复制成2N​即可,因为这个长度从环上任意一点开始,包含N​个元素的子序列。

题解代码

#include<bits/stdc++.h> using namespace std; ​ const int N=105,M=15; long long Max[N][N][M]; long long Min[N][N][M]; long long num[N],s[N]; ​ int mod10(long long val) { int res = val % 10; if (res < 0) { res += 10; // 确保负数取模结果在 [0, 9] } return res; } ​ int main() { int n,m; cin>>n>>m; ​ s[0]=0; for(int i=1;i<=n;i++) { cin>>num[i]; num[i+n]=num[i]; s[i]=s[i-1]+num[i]; } for(int i=1;i<=2*n;i++) // 循环到 2n { s[i]=s[i-1]+num[i]; // s[i] 存储 num[1] 到 num[i] 的和 (1-indexed) } for (int i = 1; i <= 2 * n; ++i) { for (int j = i; j <= 2 * n; ++j) { int val = mod10(s[j] - s[i - 1]); Max[i][j][1] = val; Min[i][j][1] = val; } } for(int k=2;k<=m;k++) { for(int len=k;len<=2 * n;len++) { for(int i=1;i<=2 * n-len+1;i++) { int j=i+len-1; Max[i][j][k]=INT_MIN; Min[i][j][k]=INT_MAX; for(int q=i + k - 2;q<j;q++) { int v=mod10(s[j]-s[q]); Max[i][j][k]=max(Max[i][j][k],Max[i][q][k-1]*v); Min[i][j][k]=min(Min[i][j][k],Min[i][q][k-1]*v); } } } } long long finalmin=INT_MAX,finalmax=INT_MIN; for(int i=1;i<=n;i++) { if(finalmin>Min[i][i+n-1][m]) finalmin=Min[i][i+n-1][m]; if(finalmax<Max[i][i+n-1][m]) { finalmax=Max[i][i+n-1][m]; } } cout<<finalmin<<endl<<finalmax; return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 5:17:30

【Docker镜像优化黄金法则】:让边缘Agent更小更快更安全

第一章&#xff1a;边缘Agent镜像优化的挑战与意义在边缘计算架构中&#xff0c;Agent作为连接终端设备与中心云平台的核心组件&#xff0c;其运行效率直接影响系统的响应速度与资源利用率。由于边缘设备通常具备有限的存储空间、计算能力和网络带宽&#xff0c;传统的大型容器…

作者头像 李华
网站建设 2026/6/21 16:48:17

前端vue3 web端中实现拖拽功能实现列表排序

类似这样的我现在要实现能够拖拽 直接能够让这个列表项 切换顺序我们可以使用前端库 也可以使用原生自带的功能我直接贴代码了template<el-form-item label"选择书籍&#xff1a;" class"book-select-container"><div class"booklist-contai…

作者头像 李华
网站建设 2026/6/23 5:41:48

VSCode+PlatfoemIO+ESP32-Cam + MB烧录器 入门测试

研究大半天的监控无法打印日志的问题&#xff0c;两个问题1、避免 println&#xff0c;改用 printf 在某些 MB 板上&#xff0c;println 会被 CDC 缓冲吞掉&#xff0c;导致监控无法输出&#xff08;很玄学&#xff0c;但真实存在&#xff09;。2、彻底禁用一切“下载相关行为”…

作者头像 李华
网站建设 2026/6/22 16:00:39

【加密PDF解析避坑指南】:Dify错误处理的5大核心策略与实战技巧

第一章&#xff1a;加密PDF解析的Dify错误处理概述在集成Dify平台进行文档智能解析时&#xff0c;加密PDF文件常引发一系列解析异常。由于PDF加密机制限制了内容的直接读取&#xff0c;Dify默认的解析流程无法获取原始文本&#xff0c;导致任务失败或返回空结果。此类问题不仅影…

作者头像 李华