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

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; }
http://www.cnnetsun.cn/news/90175.html

相关文章:

  • Web安全攻防学习图谱:90天从网安小白到漏洞猎人(超详细),看这一篇就够了!
  • 【Docker镜像优化黄金法则】:让边缘Agent更小更快更安全
  • 前端vue3 web端中实现拖拽功能实现列表排序
  • 【音视频开发必看】Dify 1.7.0音频转换避坑指南:5大常见错误及修复方案
  • VSCode+PlatfoemIO+ESP32-Cam + MB烧录器 入门测试
  • 【加密PDF解析避坑指南】:Dify错误处理的5大核心策略与实战技巧
  • 性能测试入门:使用 Playwright 测量关键 Web 性能指标
  • 从入门到精通:R语言极值分布拟合在气象数据中的4个关键步骤
  • 仅1%人掌握的建模技术:R语言金融相关性矩阵稀疏化处理实战
  • 超越传统PLM理念,定义行业新标准:全星研发项目管理APQP软件系统
  • 【安全专家亲授】私有化Dify的SSL配置秘诀:保障数据传输不被窃取
  • Vue3+JS 高级前端面试题
  • 海康威视智能工厂,是如何走向“领航”的?
  • 《深入昇腾底层:Ascend C 编程模型与高性能算子开发实战》
  • 实战 Ascend C:从零实现高性能自定义算子
  • 掌握这3种R包,轻松完成空间转录组细胞轨迹建模!
  • 【Dify Tesseract字体适配终极指南】:破解OCR识别失败的9大字体陷阱
  • Docker + 智能Agent日志管理新思路(仅限高级工程师掌握的3种架构模式)
  • 揭秘空间转录组细胞类型注释:如何用R语言精准识别每一种细胞
  • [吾爱大神原创工具] 电话号码过滤,号码排序-乱序,清除非手机号,消重,导出(依旧颜值高)
  • Dify平台Agent版本管理全解析:从入门到高可用架构设计
  • 为什么90%的生物信息分析师都在用R做RNA结构研究?真相令人震惊
  • 【稀缺资源】Dify + Tesseract 5.3多语言支持实现路径首次公开
  • 还在手动写Dify用例?Agent驱动自动化测试已成主流!
  • RSA 加密体制及其安全性分析
  • 【视频帧提取效率翻倍秘籍】:Dify帧率设置背后的黄金参数揭秘
  • 在C#上运行YOLOv11模型---CPU版
  • 关于uniapp vue2 canvas重绘元素节点时,提示cos of null相关异常警告,导致js线程崩溃,vue响应式丢失的问题
  • 【微服务稳定性提升利器】:基于Dify与Spring AI的异常熔断与恢复策略
  • concurrent hashmap原理,扩容,扩容时怎么保证线程安全?