【问题标题】:Count Sub arrays with condition?计算有条件的子数组?
【发布时间】:2015-11-04 04:04:52
【问题描述】:

我有一个包含 N 个整数和 M 对 (a,b) 的数组 -> a,b 是数组的索引。

我必须计算具有 N 个元素的数组 A 的非空连续子序列(子段)的数量,使得没有段包含 M 对中的任何一个的两个元素(简单来说,减去具有任何两个元素的段的数量)总段数中的 M 对)?

例子:

 N=5 , M=1 -> pair (1,4) then ans=13 .
 {(1),(2),(3),(4),(5),(1,2),(2,3),(3,4),(4,5),(1,3),(2,4),(3,5),(2,5)}

我尝试过的解决方案:我尝试过应用动态编程但没有通过它,然后试图贪婪地思考,然后也没有得到它。

【问题讨论】:

    标签: arrays algorithm math dynamic-programming


    【解决方案1】:

    这是 O(n + m) 的解决方案。

    对于每个索引 i,我们将在左侧找到第一个索引 j,这样我们就不能有从 j 开始的段或更早,并以 i 或更早结束。如果我们有这些索引,我们可以通过为每个索引添加 i - left[i] 来轻松获得答案。

    如何找到它?

    首先,让所有first[i]都等于0。 然后读取所有对 (a,b)(比如说 a )并使 left[b] 等于 max (左[b], a).

    在此之后,让我们使用动态规划。每个索引从左到右 i > 1, left[i] = max(left[i], left[i - 1]).

    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int MAXN = 1000000;
    int n, m;
    int LEFT[MAXN + 5];
    
    int main() {
        ios_base::sync_with_stdio(0);
    
        cin >> n >> m;
    
        for(int i = 1; i <= n; i++)
            LEFT[i] = 0;
    
        for(int i = 1; i <= m; i++) {
            int a, b;
            cin >> a >> b;
            if(a > b) swap(a, b);
            LEFT[b] = max(LEFT[b], a);
        }
    
        long long answer = 0;
        for(int i = 2; i <= n; i++)
            LEFT[i] = max(LEFT[i], LEFT[i - 1]);
        for(int i = 1; i <= n; i++)
            answer += i - LEFT[i];
        cout << answer << endl;
    }
    

    【讨论】:

    • 这不是正确的解决方案....当我的 (a1,a3) 和 (a2,a4) 有错误的配对时会发生什么情况......然后这个解决方案失败了
    • 它是如何失败的?如果 N = 4, M = 2 和对:(1, 3) 和 (2, 4),则结果为 7。 {(1), (2), (3), (4), (1,2), (2,3), (3,4)}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    • 2016-03-11
    相关资源
    最近更新 更多