洛谷题单指南-分治与倍增-P6648 [CCC2019] Triangle: The Data Structure

news/2024/9/30 15:03:17

原题链接:https://www.luogu.com.cn/problem/P6648

题意解读:在一个n行的数字三角形中,求所有边长为k的正三角形最大值之和。

解题思路:

1、枚举法

枚举每一个边长为k的三角形,在其中求max,然后累加,n最多3000,时间复杂度是n^4,显然超时。

2、倍增和ST思想

此题非常类似于RMQ问题,也就是求区间最值,只不过区间是一个三角形

可否借助ST思想?

不妨设st[i][j][k]表示从(i,j)开始,大小为2^k的三角形内最大值,a[i][j]表示三角形(i,j)位置的值

初始化:st[i][j][0] = a[i][j]

递推:

求值:

假设要计算(i,j)为顶点,边长为k的三角形内最大值

想到这里,兴匆匆的写出如下代码:

0分代码:

#include <bits/stdc++.h>
using namespace std;const int N = 3005;
int a[N][N];
int st[N][N][12]; //st[i][j][k]表示从(i,j)开始,大小为2^k的三角形内最大值
int n, k;
long long ans;int main()
{cin >> n >> k;for(int i = 1; i <= n; i++){for(int j = 1; j <= i; j++){cin >> a[i][j];st[i][j][0] = a[i][j];}}for(int l = 1; l < log2(n); l++){for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){st[i][j][l] = st[i][j][l - 1];int x = i + (1 << l - 1);for(int y = j; y <= j + (1 << l - 1); y++){st[i][j][l] = max(st[i][j][l], st[x][y][l - 1]);}}}}for(int i = 1; i + k - 1 <= n; i++){for(int j = 1; j <= i; j++){int len = log2(k);int maxijk = st[i][j][len];int x = i + k - (1 << len);for(int y = j; y <= j + k - (1 << len); y++){maxijk = max(maxijk, st[x][y][len]);}ans += maxijk;}}cout << ans;return 0;
}

原来是int st[N][N][12]爆内存了,需要进一步优化,递推式中l只依赖l-1,因此可以用滚动数组进行优化,于是有:

25分代码:

#include <bits/stdc++.h>
using namespace std;const int N = 3005;
int a[N][N];
int st[N][N][2]; //st[i][j][k]表示从(i,j)开始,大小为2^k的三角形内最大值,第三维用滚动数组优化
int n, k;
long long ans;int main()
{cin >> n >> k;for(int i = 1; i <= n; i++){for(int j = 1; j <= i; j++){cin >> a[i][j];st[i][j][0] = a[i][j];}}for(int l = 1; l <= log2(k); l++){for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){st[i][j][l % 2] = st[i][j][(l - 1) % 2];int x = i + (1 << l - 1);for(int y = j; y <= j + (1 << l - 1); y++){st[i][j][l % 2] = max(st[i][j][l % 2], st[x][y][(l - 1) % 2]);}}}}for(int i = 1; i + k - 1 <= n; i++){for(int j = 1; j <= i; j++){int len = log2(k);int maxijk = st[i][j][len % 2];int x = i + k - (1 << len);for(int y = j; y <= j + k - (1 << len); y++){maxijk = max(maxijk, st[x][y][len % 2]);}ans += maxijk;}}cout << ans;return 0;
}

究其原因,关键代码的时间复杂度是logk*N^3,需要进一步优化时间

观察代码:

红色框中是要计算从j开始,窗口长度(1<<l-1)+ 1的最大值,显然可以用单调队列优化,于是就有了以下最终版代码:

100分代码:

#include <bits/stdc++.h>
using namespace std;const int N = 3005;
int a[N][N];
int st[N][N][2]; //st[i][j][k]表示从(i,j)开始,大小为2^k的三角形内最大值,第三维用滚动数组优化
int n, k;
long long ans;
int q[N], head, tail;int main()
{cin >> n >> k;for(int i = 1; i <= n; i++){for(int j = 1; j <= i; j++){cin >> a[i][j];st[i][j][0] = a[i][j];}}for(int l = 1; l <= log2(k); l++){for(int i = 1; i <= n; i++){head = 1, tail = 0; //单调队列头、尾指针初始化int len = (1 << l - 1) + 1; //窗口大小int x = i + (1 << l - 1); //起始横坐标for(int j = 1; j <= n; j++){st[i][j][l % 2] = st[i][j][(l - 1) % 2];//去头while(head <= tail && j - q[head] + 1 > len) head++;//去尾while(head <= tail && st[x][j][(l - 1) % 2] > st[x][q[tail]][(l - 1) % 2]) tail--;//存入q[++tail] = j;   //取窗口最大值,并与i,j - len + 1位置对应的值取maxif(j >= len)st[i][j - len + 1][l % 2] = max(st[i][j - len + 1][l % 2], st[x][q[head]][(l - 1) % 2]);}}}for(int i = 1; i + k - 1 <= n; i++){for(int j = 1; j <= i; j++){int len = log2(k);int maxijk = st[i][j][len % 2];int x = i + k - (1 << len);for(int y = j; y <= j + k - (1 << len); y++){maxijk = max(maxijk, st[x][y][len % 2]);}ans += maxijk;}}cout << ans;return 0;
}

 

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

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

相关文章

确保上传的缩略图在 PbootCMS 中保持清晰

config/config.php 文件中的相关部分:// 缩略图配置 ico => array(max_width => 1920, // 最大宽度1920max_height => // 最大高度不填写代表不限制 ),清除缓存清除系统缓存修改完配置文件后,需要清除系统缓存,确保配置更新生效。 在后台管理中找到“缓存管…

象形闽都 数智榕城 | PostgreSQL中文社区技术沙龙 - 福州站

在数字化浪潮席卷的时代,数据已成为推动社会进步与企业发展的核心动力。福建,作为东南沿海的经济与文化重镇,正以崭新的姿态拥抱数智未来。为促进福建地区数据库技术的交流与发展,我们诚挚邀请您参加“象行闽都,数智榕城 —— PostgreSQL数据库技术沙龙”。活动主题: 象行…

SSL证书必须要买吗?

在当今数字化的时代,网络安全日益成为人们关注的焦点。SSL证书作为一种保障网络安全通信的工具,是否必须购买成为许多人心中的疑问。 对于企业和商业网站来说,购买SSL证书往往是非常必要的。 首先,从用户信任的角度来看,当用户访问一个带有SSL证书的网站时,浏览器地址栏会…

PBOOTCMS的水印功能如何使用?pbootcms设置的水印为何没生效?

在 PbootCMS 中,水印功能主要用于给新上传的图片添加水印。如果你发现开启了水印功能但前端仍然没有水印,可能是因为以下几个原因:只对新上传的图片生效:水印功能仅对新上传的图片生效,之前上传的图片不会自动加上水印。 水印配置未生效:可能是因为水印配置没有正确设置或…

prometheus学习笔记之Grafana 常用操作

一、Panel 设置 1.单位设置2.Panel名称修改3.曲线别名 修改前修改后 4.曲线排序 5.曲线复制6.曲线静默 7.Panel复制 当前dashboard中复制跨dashboard或folder在其他dashboard中操作8.设置告警线设置告警条件其他按提示填写如果触发告警规则 则页面会有提示9.row效果如下:10.自…

pbootcms模板幻灯片调用代码大全

在 PbootCMS 中,模板自带的幻灯片功能可以通过 {pboot:slide} 标签来实现。下面详细介绍该标签的使用方法及其控制参数。 幻灯片标签详解 标签语法html{pboot:slide gid=* num=*}<!-- 幻灯片内容 --> {/pboot:slide}控制参数gid=*分组:必填参数,用于指定需要输出的幻灯…

PbootCMS网站转移后无法打开报错提示“No input file specifed”

检查根目录是不是含有.user.ini文件,有的话删除掉,一般就可以了。如果还不行或者是在本地尝试重启Apache或者Nginx服务。 扫码添加技术【解决问题】专注中小企业网站建设、网站安全12年。熟悉各种CMS,精通PHP+MYSQL、HTML5、CSS3、Javascript等。承接:企业仿站、网站修改…

@Validated和@Valid简单使用

当使用apifox时,我们需要必传字段做标记,可以使用 @NotEmpty(message = "id不能为空")同时在入参位置添加 @Valid @RequestBody其中 @Valid起到关键作用效果图 同时在apifox中 这样测试或者前端去测试接口的时候就知道哪些字段一定要传,哪些是非必要的 @NotEmpty引…