查找数组中的最小更改数以进行 k 算术级数

Posted

技术标签:

【中文标题】查找数组中的最小更改数以进行 k 算术级数【英文标题】:Find minimum number of changes in array to make k-arithmetic progression 【发布时间】:2018-06-19 10:09:56 【问题描述】:

我最近遇到了这个问题:

在挑战中,给你一个包含 n 个数字和一个整数 k 的数组。在一分钟内,您可以将数组的任何元素更改为您想要的任何整数。找出满足以下条件的最少时间:对于所有 i 从到 1,n - 1,a[i] - a[i - 1] = k。由于 n, k

我贪婪地意识到这个问题可能是DP,但我找不到答案。这个topic 类似,但那里的答案没有用(在我看来)。我只是在寻找一个伪(或 cpp)代码。

UPD:我在 O(n^2) 中编写了一个蛮力解决方案,如果它对您有帮助,这里是代码:

    #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<double> vd;
typedef vector<bool> vb;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<pi> vp;
typedef vector<pl> vpl;

int main()

    ios_base::sync_with_stdio(false); 
    cin.tie(nullptr); 
    cout.tie(nullptr); 
    cerr.tie(nullptr);  

    int n, k;
    cin >> n >> k;

    vi a(n);
    for (auto& i : a)
        cin >> i;

    int res = INT32_MAX;
    for (int i = 0; i < n; ++i)
        int s = a[i], sol = 0;
        for (int j = i + 1; j < n; ++j)
            s += k;
            if (a[j] != s)
                ++sol;
        
        s = a[i];
        for (int j = i - 1; j > -1; --j)
            s -= k;
            if (a[j] != s)
                ++sol;
        
        res = min(sol, res);
    

    cout << res << '\n';

【问题讨论】:

您是否尝试过自己将动态规划应用到这个问题上?您具体在哪里对此有疑问?这里的人更有可能帮助在问题中表现出实际努力的人。 @SergGr 我的尝试完全错误。我认为这对任何人都没有帮助,而是我在 UPD 中给予了蛮力。 在类似的主题 ***.com/questions/50922702 我已被警告问题来自正在进行的比赛 哦,我不知道。我应该删除我的答案吗?现在感觉有点晚了。 @Qubit 是的,你应该在比赛结束前删除你的答案。 【参考方案1】:

我不完全确定这是否适合这里,如果我理解正确,您是在要求一种算法。

您需要找到最少数量的元素进行更改,以满足进度。 我建议你减去斜率,即a[i]-=k*i,现在你所要做的就是找到新数组中最常出现的数字(更重要的是,它出现了多少次)。基本上,您想问有多少点位于某些线上 (a[i]=k*i+m),因此您减去斜率并计算每个 m 的出现次数。最常出现的m 的值具有最多的具有适当值的点,所以我们要做的就是修复所有其他点。

鉴于您的值可能很大(我假设),您可以使用std::map 进行计数,这应该给您最坏的 O(n*log(n))。那么最终结果就是n-maxReps,其中maxReps是新数组中重复次数最多的值的重复次数。正如我们所说,我们仍然需要更改的值的数量才能满足我们的条件。

基本上,您只需计算必须修复的点数,以便它们位于您的线上。

我将把实现留给你。

【讨论】:

应该很清楚,最坏的情况,看问题。

以上是关于查找数组中的最小更改数以进行 k 算术级数的主要内容,如果未能解决你的问题,请参考以下文章

leetcode - 二分查找

简单的指针算术问题

bzoj 4373: 算术天才⑨与等差数列 hash

C#中的大数组算术

AC日记——算术天才⑨与等差数列 bzoj 4373

[BZOJ4373]算术天才⑨与等差数列