IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Arithmetic Operations(分类暴力dp) -> 正文阅读

[数据结构与算法]Arithmetic Operations(分类暴力dp)

Arithmetic Operations

[Link](Problem - E - Codeforces)

题意

给你一个数组 a a a,每次操作可以选择一个 a i a_i ai?将其变成任意一个数 x x x,问你最少操作多少次使之变成一个等差数列。

思路

? 不好判断修改哪几个数,但是哪些数不变比较好判断。我们可以枚举公差 d d d,首先只考虑 d > = 0 d>=0 d>=0的情况对于 d < 0 d<0 d<0的情况,将原数组反转即可,对于每个 d d d我们让 a i ? ( i ? 1 ) ? d a_i-(i-1)*d ai??(i?1)?d,相当于把偏移量减去,之后剩下的最多的就是我们要留下数,剩下的都是需要改变的。设 m = m a x ( a i ) m=max(a_i) m=max(ai?),我们的公差不会超过这个数,例如 a 1 , a 2 , a 3 a_1,a_2,a_3 a1?,a2?,a3?三个数 m = a 2 m=a_2 m=a2?,如果 d < = m d<=m d<=m则我们最多只需要改变 a 1 , a 3 a_1,a_3 a1?,a3?,若 d > m d>m d>m则必须修改 a 1 , a 2 , a 3 a_1,a_2,a_3 a1?,a2?,a3?

? 但是这样枚举复杂度为 O ( n m ) O(nm) O(nm)太高了,考虑分类对于 d < m d<\sqrt m d<m ?的我们枚举 d d d,复杂度为 O ( n m ) O(n\sqrt m) O(nm ?)

? 对于 d ≥ m d\ge \sqrt m dm ?情况,首先我们来证任意一个 a i a_i ai?最多可能和 a i + m a_{i+\sqrt m} ai+m ??一起保留,假设 j > i + m j>i+\sqrt m j>i+m ?,则 a j ? a i ≥ d × m > m a_j-a_i\ge d\times \sqrt m >m aj??ai?d×m ?>m,由于 m a x ( a i ) = = m max(a_i)==m max(ai?)==m因此显然不对,所以 i i i j > i + m j>i+\sqrt m j>i+m ?的数只能保留一个。由于要让一些数有相同的 d d d,因此将 i → j ( j ≤ i + m ) i\to j(j\le i+\sqrt m) ij(ji+m ?)连一条边,边权为 a j ? a i j ? i = d \frac{a_j-a_i}{j -i}=d j?iaj??ai??=d(如果可以整除),最多会有 n m n\sqrt m nm ?条边,我们相当于要找最多的具有相同边权的边,由于是个拓扑图,可以直接用 f [ i ] [ j ] : 以 i 结 尾 的 为 d 的 边 有 多 长 f[i][j]:以i结尾的为d的边有多长 f[i][j]:id,转移即可,复杂度为 O ( n m ) O(n\sqrt m) O(nm ?)

? 由于第二部分的图比较稀疏,因此实际上以小于 m \sqrt m m ?来分类更优一些。

Code

#include <bits/stdc++.h>
#define x first
#define y second
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 1e5 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-8, pi = acos(-1), inf = 1e20;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int n, m, k;
int S = 200;
int a[N];
int b[N * 200];
int solve() {
    int res = 0;
    for (int d = 0; d < S; d ++) {
        for (int i = 0; i < n; i ++) {
            b[a[i] + d * (n - i)] ++;
            res = max(res, b[a[i] + d * (n - i)]);
        }
        for (int i = 0; i < n; i ++) 
            b[a[i] + d * (n - i)] --;
        
    }

    map<int, int> f[n + 1];

    for (int i = 0; i < n; i ++)
        for (int j = max(0, i - N / S); j < i; j ++) {
            int d = (a[i] - a[j]) / (j - i);
            int r = (a[i] - a[j]) % (j - i);
            if (d >= S && !r) {
                f[i][d] = max(f[i][d], f[j][d] + 1);
                res = max(res, f[i][d] + 1);
            }
        }

    return res;
}
int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    cin >> n;
    for (int i = 0; i < n; i ++) cin >> a[i];
    int ans = solve();
    reverse(a, a + n);
    ans = max(ans, solve());
    cout << n - ans << '\n';
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:49:54  更:2022-03-22 20:52:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 1:52:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码