• [hdu5256]LIS模型


    题目:有一个数列A1,A2...An,修改数量最少的元素,使得这个数列严格递增。无论是修改前还是修改后,每个元素都必须是整数。

    思路: 修改数量最少的元素使得这个数列严格递增,等价于让数量最多的元素不变,然后修改其余的元素。也就是从序列里面选尽量多的数,使得其它数修改后能形成一个单调递增序列。这跟LIS很像,不过多了个限制,我们尝试用数学式子来描述这个限制,a[i]-a[j]>=i-j,i>j,a[i],a[j]∈LIS,变形就是a[i]-i>=a[j]-j。一种自然的想法就产生了,将原序列做个变换,a[i]->a[i]-i,然后对新序列求最长非降序列,那么最长非降序列里的数的个数就是不变的数的最大个数,用n减去就是答案。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #pragma comment(linker, "/STACK:10240000,10240000")
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <algorithm>
    #include <queue>
    using namespace std;
     
    int dp[123456], n, a[123456];
     
    int LIS(int *from, int *to) {
        dp[0] = -1e9;
        for (int i = 1; i <= n; i ++) dp[i] = 1e9;
        int ans = 0;
        for (int *pint = from; pint < to; pint ++) {
            int pos = upper_bound(dp, dp + n, *pint) - dp - 1;
            dp[pos + 1] = min(dp[pos + 1], *pint);
            ans = max(ans, pos + 1);
        }
        return ans;
    }
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt""r", stdin);
    #endif // ONLINE_JUDGE
        int T, cas = 0;
        cin >> T;
        while (T --) {
            cin >> n;
            for (int i = 0; i < n; i ++) {
                scanf("%d", a + i);
                a[i] -= i;
            }
            printf("Case #%d: %d ", ++ cas, n - LIS(a, a + n));
        }
        return 0;
    }
  • 相关阅读:
    关于Web 打印的三种方法
    禁止另存为 禁止复制 禁止右键 JS
    无限数据递归
    VS2003+Ajax Div文本框输入提示
    C#关于日期月天数和一年有多少周及某年某周时间段的计算
    git代码冲突
    RabbitMQ死信队列
    Elementui:ElContainer布局
    mxml调用as
    用自己的MapServer,解决沙箱冲突
  • 原文地址:https://www.cnblogs.com/jklongint/p/4579042.html
Copyright © 2020-2023  润新知