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

数据结构优化DP总结

单调栈:Codeforces Round 622 (Div. 2) C2. Skyscrapers (hard version)

在这里插入图片描述
简单来讲就是最后需要呈现出一个单峰数组,使得总高度最高。

最开始想到暴力枚举每一个元素都充当最高的“单峰”,但是这里的 n 过大,这样枚举肯定会TLE。

那就考虑能不能单调线性的考虑每个元素作为最高点的时候的解是多少呢?

这里就需要借助我们的 单调栈,维护一个单调递增的序列:

  • 这里仅以正序遍历为例:f[i]表示的是以i为单峰时1 — i 所有数组能产生的最大贡献,根据单调栈的性质,stk.top()就是上一个最近的小于 a[i] 的元素的下标,所以加上这中间所有的楼产生的贡献(由于单调栈的性质,这段中所有大于a[i] 的元素一定会被弹出,同时减去他们之前产生的贡献)。
#include<bits/stdc++.h>

using namespace std;

#define int long long

signed main() {
    int n, sum = 0;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    stack<int> stk;
    vector<int> f(n + 1, 0);
    sum = 0;
    for (int i = 1; i <= n; i++) {
        while(stk.size() && a[stk.top()] >= a[i]) {
        //先弹出所有大于a[i]的楼的下标,因为保证要单增
            int j = stk.top();
            stk.pop();
            sum -= (j - (stk.empty() ? 0 : stk.top())) * a[j];
            // 减去这些楼之前所产生的贡献
        }
        sum += (i - (stk.empty() ? 0 : stk.top())) * a[i]; //加上目前这栋楼所产生的贡献
        stk.push(i);
        f[i] += sum;
    }
    sum = 0;
    while(!stk.empty()) stk.pop(); 
    for (int i = n; i >= 1; i--) {
        while(stk.size() && a[stk.top()] >= a[i]) {
            int j = stk.top();
            stk.pop();
            sum -= ((stk.empty() ? n + 1 : stk.top()) - j) * a[j];
        }
        sum += ((stk.empty() ? n + 1 : stk.top()) - i) * a[i];
        stk.push(i);
        f[i] += sum - a[i];
    }

    auto p = max_element(f.begin() + 1, f.end()) - f.begin();
    //cout << p << endl;
    for (int i = p - 1; i >= 1; i--) {
        a[i] = min(a[i], a[i + 1]);
    }
    for (int i = p + 1; i <= n; i++) {
        a[i] = min(a[i], a[i - 1]);
    }
    for (int i = 1; i <= n; i++) {
        cout << a[i] << " \n"[i == n];
    }

    return 0;
}

建议先熟练掌握单调栈再来理解这题。

树状数组:Codeforces Round 1013 (Div. 3) F. Igor and Mountain

在这里插入图片描述
其实也不一定需要树状数组,用前缀和也能达到一样的效果,只是树状数组比较好写,不费脑子。

简单来说就是如果暴力枚举转移的话会超时,所以就需要记录下整个区间的某种贡献,然后一起转移,这样就可以省下很多的时间。

i64 mod = 998244353;
  
double get_dist(int a, int b, int c, int d) {
	double dx = fabs(a - c);
	double dy = fabs(b - d);
	return sqrt(dx * dx + dy * dy);
}
  
template <typename T>
class Fenwick {
public:
	int n;
	std::vector<T> a;
	Fenwick(int n_ = 0) {
		init(n_);
	}
	void init(int n_) {
		n = n_;
		a.assign(n + 1, T{});
	}
	void add(int x, const T &v) {
		for (int i = x; i <= n; i += i & -i) {
			a[i] = (a[i] + v % mod + mod) % mod;
		}
	}
	// 查询位置 [1, x] 的前缀和
	T sum(int x) {
		T ans{};
		for (int i = x; i > 0; i -= i & -i) {
			ans = (ans + a[i] % mod + mod) % mod;
		}
		return ans;
	}
	// 查询区间 [l, r] 的区间和
	T rangeSum(int l, int r) {
		return (sum(r) - sum(l - 1) + mod) % mod;
	}
	int select(const T &k) {
		int x = 0;
		T cur{};
		for (int i = 1 << std::__lg(n); i; i /= 2) {
			if (x + i <= n && cur + a[x + i] <= k) {
				x += i;
				cur = cur + a[x];
			}
		}
		return x;
	}
};
  
void solve()
{
	int n, m, d1, d2;
	cin >> n >> m >> d1;
	for (int i = 0; i <= d1; i++) {
		if(i * i + 1 <= d1 * d1) {
			d2 = i;
		}
	}
  
	vector<string> g(n + 1);
	for (int i = 1; i <= n; i++) {
		cin >> g[i];
		g[i] = ' ' + g[i];
	}
	int ans = 0;
	vector<Fenwick<int>> f(n + 1, Fenwick<int>(m + 1)), nf(f);
	for (int j = 1; j <= m; j++) {
		if (g[n][j] == 'X') {
            f[n].add(j, 1);
		}
	}
	for (int j = 1; j <= m; j++) {
		if (g[n][j] == 'X') {
            nf[n].add(j, f[n].rangeSum(max(1LL, j - d1), min(j + d1, m)));
		}
	}
	// for (int j = 1; j <= m; j++) {
	//     cout << nf[n].rangeSum(j, j) << ' ';
	// }
	// cout << endl;
	for (int i = n - 1; i >= 1; i--) {
		for (int j = 1; j <= m; j++) {
			if (g[i][j] == 'X') {
				f[i].add(j, nf[i + 1].rangeSum(max(1LL, j - d2), min(j + d2, m)));
			}
		}
		for (int j = 1; j <= m; j++) {
			if (g[i][j] == 'X') {
				nf[i].add(j, f[i].rangeSum(max(1LL, j - d1), min(j + d1, m)));
			}
		}
	}
	ans = nf[1].sum(m);
	cout << (ans + mod) % mod << endl;
}
  
http://www.dtcms.com/a/107584.html

相关文章:

  • SvelteKit 最新中文文档教程(17)—— 仅服务端模块和快照
  • 智能配电箱:重塑未来电力管理的核心枢纽
  • 大模型显卡网络
  • 爱普生RX8901CE实时时钟模块赋能智能监控系统的精准
  • 某某航空 同盾 blackbox 补环境
  • 华为云数据库服务实践
  • 如何解决跨系统审批慢、人工干预多的问题?
  • es自定义ik分词器中文词库实现热更新
  • Elasticsearch 证书问题解决
  • 基于pycharm的YOLOv11模型训练方法
  • mac 最新的chrome版本配置selenium的方式
  • React 文件上传新玩法:Aliyun OSS 加持的智能上传组件
  • d202542
  • 架构师面试(二十五):分布式存储 Leader 设计
  • 元素定位-cssSelector
  • SSM框架学习(Day-1)
  • Kubernetes 入门篇之 Node 安装与部署
  • 视频分析设备平台EasyCVR视频结构化AI智能分析:筑牢校园阳光考场远程监控网
  • 基于 Cesium.js 的交互式绘图工具库
  • IO 端口与 IO 内存
  • 电流与电压的守护者
  • 3. 矩阵置零
  • Vue + Axios + Mock.js 全链路实操:从封装到数据模拟的深度解析
  • 两种方法证明r(A+B)<=r(A,B)<=r(A)+r(B)
  • 【一起来学kubernetes】33、Hpa使用详解
  • 常见操作系统特点及区别对比
  • 双翌闪耀2025上海机器视觉展,以创新技术赋能产业未来
  • C++中的继承
  • P2782 友好城市
  • 私有云(三)双节点部署openstack