此篇博客总结常见的LIS模型变形的解法。

-------------------------------------------------------------------

〇、LIS的$O(NlogN)$复杂度的dp和$O(N^2)$复杂度的dp就不写了。

一、最长不下降子序列

  把$O(NlogN)$复杂度的dp中,查找$\ge a[i]$的函数lower_bound改为查找$> a[i]$的函数upper_bound即可。

#include<bits/stdc++.h>
using namespace std;
;

int n, a[MAXN], dp[MAXN];
int main(){
    freopen("input.txt", "r", stdin);
    freopen("output2.txt", "w", stdout);
    while(~scanf("%d", &n)){
        ;i < n;++i)scanf("%d", a + i);
        memset(dp, 0x3f, sizeof(dp));
        ;i < n;++i){
            int p = upper_bound(dp, dp + n, a[i]) - dp;
            dp[p] = a[i];
        }
        cout << (lower_bound(dp, dp + n, 0x3f3f3f3f) - dp) << endl;
    }
    ;
}

二、LIS输出方案

  1、输出任意方案(以下方法其实是输出下标字典序最大的一个LIS)

#include<bits/stdc++.h>
using namespace std;
;

int n, a[MAXN], dp[MAXN], par[MAXN];
map<int, int> mp;

void print(int x){
    if(~par[x])print(par[x]);
    printf("%d ", a[x]);
}

int main(){
    freopen("input.txt", "r", stdin);
    freopen("output2.txt", "w", stdout);
    while(~scanf("%d", &n)){
        ;i < n;++i)scanf("%d", a + i);
        memset(dp, 0x3f, sizeof(dp));
        memset(par, -, sizeof(par));
        mp.clear();
        ;i < n;++i){
            int p = lower_bound(dp, dp + n, a[i]) - dp;
            dp[p] = a[i];
            mp[a[i]] = i;
            )par[i] = mp[dp[p - ]];
        }
        int len = lower_bound(dp, dp + n, 0x3f3f3f3f) - dp;
        printf("%d\n", len);
        print(mp[dp[len - ]]);
        printf("\n");
    }
    ;
}

  2、输出LIS下标字典序最小的方案

#include<bits/stdc++.h>
using namespace std;
;

int n, a[MAXN], dp[MAXN], par[MAXN];
map<int, int> mp;
vector<int> v[MAXN];

void print(int x, int y) {
    ) {
        ; i < v[x - ].size(); ++i) {
            ][i]] < a[v[x][y]]){
                print(x - , i);
                break;
            }
        }
    }
    printf("%d ", a[v[x][y]]);
}

int main() {
    freopen("input.txt", "r", stdin);
    freopen("output2.txt", "w", stdout);
    while(~scanf("%d", &n)) {
        ; i < n; ++i)scanf("%d", a + i);
        ; i < n; ++i)v[i].clear();
        memset(dp, 0x3f, sizeof(dp));
        memset(par, -, sizeof(par));
        mp.clear();
        ; i < n; ++i) {
            int p = lower_bound(dp, dp + n, a[i]) - dp;
            dp[p] = a[i];
            mp[a[i]] = i;
            )par[i] = mp[dp[p - ]];
            v[p].push_back(i);
        }
        int len = lower_bound(dp, dp + n, 0x3f3f3f3f) - dp;
        printf("%d\n", len);
        print(len - , );
        printf("\n\n");
    }
    ;
}

  3、输出数值字典序最小的方案

  朴素的想法:在第2步的基础上,把所有方案找出来,然后比较数值字典序。

  4、输出公差为$d$的LIS(此LIS不一定是最长上升子序列,但肯定是最长的上升的公差为$d$的等差数列)(任意一个即可)

  例题:http://codeforces.com/contest/977/problem/F

/********************template head********************/
#include<bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
#define mk(x, y) make_pair(x, y)
#define pln() putchar('\n')
#define cln() (cout << '\n')
#define fst first
#define snd second
#define MOD 1000000007LL
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
;
/********************template head********************/

int n, d, a[MAXN], dp[MAXN], par[MAXN], len;
map<int, int> mp;

void dfs(int x) {
    if(~par[x])dfs(par[x]);
    printf("%d ", a[x]);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    //freopen("output2.txt", "w", stdout);
#endif // ONLINE_JUDGE
    while(~scanf("%d%d", &n, &d)) {
        ; i < n; ++i)scanf("%d", a + i);
        memset(par, -, sizeof(par));
        mp.clear();
        ; i < n; ++i) {
            map<int, int>::iterator it = mp.find(a[i] - d);
            ;
            else {
                dp[i] = dp[it->snd] + ;
                par[i] = it->snd;
            }
            mp[a[i]] = i;
        }
        int p = max_element(dp, dp + n) - dp;
        printf("%d\n", dp[p]);
        dfs(p);
        printf("\n");
    }
    ;
}

LIS系列总结的更多相关文章

  1. 动态规划精讲(一)A单串

    单串 单串 dp[i] 线性动态规划最简单的一类问题,输入是一个串,状态一般定义为 dp[i] := 考虑[0..i]上,原问题的解,其中 i 位置的处理,根据不同的问题,主要有两种方式: 第一种是 ...

  2. 小明系列问题――小明序列(LIS)

    小明系列问题――小明序列 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  3. hdu4521 小明系列的问题——小明序列(LIS变种 (段树+单点更新解决方案))

    链接: huangjing 题目:中文题目 思路: 1:这个题目假设去掉那个距离大于d的条件,那么必定是一个普通的LIS.可是加上那个条件后就变得复杂了.我用的线段树的解法. . .就是採用延迟更新的 ...

  4. hdu 4521 小明系列问题——小明序列(线段树+DP或扩展成经典的LIS)

    小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  5. 小明系列问题——小明序列(Lis 相距大于d的单调上升子序列)

    小明系列问题——小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  6. hdu_4521_小明系列问题——小明序列(LIS)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4521 题意:中文题,不解释 题解:这题就是LIS的加强版,可以用二分的nlogn来做,也可以用线段树的 ...

  7. querySelectorAll 方法相比 getElementsBy 系列方法区别

    最近有人问到querySelectorAll 方法相比 getElementsBy 系列方法区别,一时没想起来说些什么,今天查下文档,总结一下它们的区别,以便自己理解. 1. W3C 标准queryS ...

  8. hdu----(4521)小明系列问题——小明序列

    小明系列问题——小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tota ...

  9. 8.3 LIS LCS LCIS(完结了==!)

    感觉这个专题真不好捉,伤心了,慢慢啃吧,孩纸 地址http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28195#overview 密码  ac ...

随机推荐

  1. [Checking for libstdc++-4.4.4-13.el6-i686; Not found. Failed] 的解决。

    单纯 yum install libstdc++-4.4.4.i686 是不行的. 应该安装 yum install libstdc++-devel.i686 顺带就能装上需要的lib 真够变态的. ...

  2. arcgis api for silverlight开发系列之二:缓存图层与动态图层及图层总结 .

    本文摘自:http://blog.csdn.net/leesmn/article/details/6916458(很优秀的博客)   作为ESRI的平台的一份子arcgis api for silve ...

  3. UVA-1153 Keep the Customer Satisfied (贪心)

    题目大意:有n件工作,做每件工作的消耗时间为s,截止时间为d,问最多能做完几件工作. 题目分析:贪心策略:优先做截止时间靠前的,一旦做不完当前工作,则从已经做过的工作中删去一件耗时最长的,用当前工作取 ...

  4. 115. Distinct Subsequences *HARD* -- 字符串不连续匹配

    Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...

  5. App6种常见的数据加载设计

    App6种常见的数据加载设计 设计师在进行APP设计的设计时,往往会更加专注于界面长什么样,界面和界面之间怎么跳转,给予用户什么样的操作反馈,却偏偏特别容易忽略掉一个比较重要的环节,就是APP数据加载 ...

  6. MsWord 操作总结

    转自(http://www.cnblogs.com/eye-like/p/4121219.html) Msdn上的word操作api(不过只有英文版,英文差的先闪过) Word2007的API:htt ...

  7. openfalcon源码分析之graph

    openfalcon源码分析之graph 本节内容 graph功能 graph源码分析 2.1 graph中重要的数据结构 2.2 graph的简要流程图 2.3 graph处理数据过程 2.4 gr ...

  8. Spartan6上软核系统自定义外设调用AXI Stream FFT经验

    这几天希望能在Spartan系列新品xc6slx16csg324-2运行带有FFT的软核处理系统,基本系统早就搭建好了.需要做的就是建立一个封装有Xilinx提供的FFT IP的自定义外设.由于Xil ...

  9. android 知识小结-1

    Java哪些数据结构是线程安全的,CurrentHashMap的原理 ConcurrentHashMap.ConcurrentSkipListMap.ConcurrentSkipListSet.Con ...

  10. 【LeetCode 144_二叉树_遍历】Binary Tree Preorder Traversal

    解法一:非递归 vector<int> preorderTraversal(TreeNode* root) { vector<int> res; if (root == NUL ...