A HDU 1025 Constructing Roads In JGShining's Kingdom
    B POJ 3903 Stock Exchange
    C OpenJ_Bailian 1065 Wooden Sticks
    D OpenJ_Bailian 1631 Bridging signals
    E OpenJ_Bailian 1952 BUY LOW, BUY LOWER
    F OpenJ_Bailian 2533 Longest Ordered Subsequence
    G OpenJ_Bailian 1692 Crossed Matchings
    H HDU 2881 Jack's struggle

点击题号进入题目链接

-----

A hdu 1025

题意:

  两条平行直线,每条线上n个点,从1-n顺序安放

  每个点想与另一个直线上的一个目标点连线,

  每个点的匹配对象不会重复,不会多余

  要求匹配过程中不能出现交叉的连线

  求最大匹配数量

分析:

  LIS的简单转化

  由于不能交叉,也没有重复的匹配点

  因此,记子序列{Ai}为最终选出的所有进行匹配的点中,第i个点所对应的目标点编号

  显然,当Ai的值为j时,后续Ai+1....都只能大于j

  简单来说:Ai==j 时 Ai+1>j,转化一下就是 Ai<AI+1.......

  也就是一个单调上升子序列

  答案求的最大匹配数量,也就是最长上升子序列的长度了

  注意,这里用朴素的算法无法达到要求的复杂度,需要进行二分优化

 /**********************
*@Name:
*
*@Author: Nervending
*@Describtion:
*@DateTime:
***********************/
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+;
const int INF=0x3f3f3f3f;
int road[maxn];
int dp[maxn];
const int inf = 0x7fffffff;
int main(){
int c=;
int n;
while((scanf("%d",&n))!=EOF) {
for(int i=; i<=n; i++) {
dp[i]=inf;
}
for(int i=; i<n; i++) {
int tmp1,tmp2;
scanf("%d%d",&tmp1,&tmp2);
road[tmp1]=tmp2;
}
int len=;
for(int i=; i<=n; i++) {
*lower_bound(dp,dp+n,road[i])=road[i];
}
len = lower_bound(dp,dp+n,inf)-dp;
if(len==) {
cout<<"Case "<<c++<<":"<<endl;
cout<<"My king, at most 1 road can be built."<<endl;
} else {
cout<<"Case "<<c++<<":"<<endl;
cout<<"My king, at most "<<len<<" roads can be built."<<endl;
}
cout<<endl;
}
return ;
}

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

B POJ 3903

题意:

  给一个数列,求他的最大上升子序列

分析:

  二分优化LIS的裸题

  直接看代码

 /**********************
*@Name:
*
*@Author: Nervending
*@Describtion:
*@DateTime:
***********************/
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
using namespace std;
const int maxn=1e6+;
const int INF=0x3f3f3f3f;
int num[maxn];
int dp[maxn];
int n;
int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
while((scanf("%d",&n))!=EOF) {
memset(dp,INF,sizeof dp);
for(int i=; i<n; i++) {
scanf("%d",&num[i]);
}
int len=;
for(int i=; i<n; i++) {
*lower_bound(dp,dp+n,num[i])=num[i];
}
len = lower_bound(dp,dp+n,INF)-dp;
cout<<len<<endl;
}
return ;
}

---------

C POJ 1065

题意:

  给一些物品,有重量和大小2个性质,要对它们进行处理

  处理第一个物品,需要1分钟,

  对于后续的物品,如果重量和大小都大于上一个物品,则不需要时间

  否则需要1分钟

  对于每组物品,求出最小的处理时间

分析:

  单看一种属性,是单纯的LIS而已,但出现了2个属性,就需要转化了

  首先,对于重量和大小可以分开处理

  把所有的物品按照大小排序,大小一样就按照重量排序

  这样,遍历过程中所有物品的大小就一定是递增的,其实就只需要对重量找LIS就行

  每次找LIS,处理掉,然后再找下一个.期间使用二分优化,直到结束,最后答案就是LIS的数量

  但上面的做法太麻烦,实际上有更好的方法

  对于每次取LIS,如果是第i个,则前面所有重量小于Wi的物品都会被处理,

  如果多个一样重量则减少一个,是哪个不影响答案

  这样,我们会发现,最重的物品一定会是某一个LIS的最后一个

  而每次的LIS终点,之后也一定不存在比它更重的物品了,而之前可能存在比它重的

  经过简单的推广思考,实际上只要能找到所有的LIS终点,显然这些LIS的处理顺序是无所谓的

  而手推几组数据,可以发现所有LIS的终点,其最后一个物品的重量一定是递减的

  简单来说,如果不是递减的,则当前的LIS就一定不是LIS,至少可以再加长一个

  转化到最后,可以发现,LIS的最后一个物品的质量,组成了一个最长的单调递减序列

  而这个序列的长度,也就是LIS的个数,也就是答案

  所以最佳的解法是:

    对于所有的物品,按照大小排序,一致就按照重量排序,最后再根据重量找出一个最长单调递减子序列,长度即为答案

在第二种方法+二分优化,最终速度非常快

 /**********************
*@Name:
*
*@Author: Nervending
*@Describtion:
*@DateTime:
***********************/
#include <bits/stdc++.h>
#define oj
using namespace std;
const int maxn=1e6+;
const int INF=0x3f3f3f3f;
typedef pair<int,int> p;
p num[maxn];
int dp[maxn];
int n;
int vis[maxn];
int main(){
#ifndef oj
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int casn;
scanf("%d",&casn);
while(casn--) {
memset(vis,false,sizeof vis);
memset(dp,-,sizeof dp);
scanf("%d",&n);
for(int i=; i<n; i++) {
scanf("%d%d",&num[i].first,&num[i].second);
}
sort(num,num+n);
for(int i=; i<n; i++) {
*lower_bound(dp,dp+n,num[i].second,greater<int>())=num[i].second;
} int ans = lower_bound(dp,dp+n,-,greater<int>())-dp;
printf("%d\n",ans);
}
#ifndef oj
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return ;
}

----

D poj 1631

题意:

  和A差不多

分析:

  和A差不多,需要使用二分优化

 /**********************
*@Name:
*
*@Author: Nervending
*@Describtion:
*@DateTime:
***********************/
#include <bits/stdc++.h> using namespace std;
const int maxn=1e6+;
const int INF=0x3f3f3f3f;
int num[maxn];
int dp[maxn];
int n;
int vis[maxn];
int main(){
//#define test
#ifdef test
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif int casn;
scanf("%d",&casn);
while(casn--) {
memset(vis,false,sizeof vis);
memset(dp,INF,sizeof dp);
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d",&num[i]);
}
for(int i=;i<n;i++){
*lower_bound(dp,dp+n,num[i])=num[i];
}
int ans=lower_bound(dp,dp+n,INF)-dp;
printf("%d\n",ans);
}
#ifdef test
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return ;
}

-----

...懒得写了,明天更新

专题2:最长上升子序列LIS的更多相关文章

  1. 2.16 最长递增子序列 LIS

    [本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...

  2. 最长上升子序列LIS(51nod1134)

    1134 最长递增子序列 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递 ...

  3. 动态规划(DP),最长递增子序列(LIS)

    题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(d ...

  4. 【部分转载】:【lower_bound、upperbound讲解、二分查找、最长上升子序列(LIS)、最长下降子序列模版】

    二分 lower_bound lower_bound()在一个区间内进行二分查找,返回第一个大于等于目标值的位置(地址) upper_bound upper_bound()与lower_bound() ...

  5. 题解 最长上升子序列 LIS

    最长上升子序列 LIS Description 给出一个 1 ∼ n (n ≤ 10^5) 的排列 P 求其最长上升子序列长度 Input 第一行一个正整数n,表示序列中整数个数: 第二行是空格隔开的 ...

  6. 最长回文子序列LCS,最长递增子序列LIS及相互联系

    最长公共子序列LCS Lintcode 77. 最长公共子序列 LCS问题是求两个字符串的最长公共子序列 \[ dp[i][j] = \left\{\begin{matrix} & max(d ...

  7. 一个数组求其最长递增子序列(LIS)

    一个数组求其最长递增子序列(LIS) 例如数组{3, 1, 4, 2, 3, 9, 4, 6}的LIS是{1, 2, 3, 4, 6},长度为5,假设数组长度为N,求数组的LIS的长度, 需要一个额外 ...

  8. 1. 线性DP 300. 最长上升子序列 (LIS)

    最经典单串: 300. 最长上升子序列 (LIS) https://leetcode-cn.com/problems/longest-increasing-subsequence/submission ...

  9. 最长上升子序列(LIS)模板

    最长递增(上升)子序列问题:在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]<a[j],这样最长的子序列称为最长递增(上升)子序列. 考虑两个数a[x ...

随机推荐

  1. Kafka技术内幕 读书笔记之(六) 存储层——日志的读写

    -Kafka是一个分布式的( distributed ).分区的( partitioned ).复制的( replicated )提交日志( commitlog )服务 . “分布式”是所有分布式系统 ...

  2. Linux记录- Linux下限制rm -rf /

    操作说明: 为了防止在linux下执行操作的时候误操作rm -rf /,或者rm -rf 一些比较重要的目录,我们做以下操作来限制rm的删除 1.下载源码安装包 https://raw.githubu ...

  3. C#设计模式(3)——抽象工厂模式

    1.抽象工厂模式介绍 上一篇我们了解了工厂模式,知道工厂模式可以解决简单工厂的缺陷(简单工厂添加新产品时要修改工厂类,不符合开闭原则),但是简单工厂和工厂模式都是只生产一种产品(前边的简单工厂和工厂都 ...

  4. idea使用maven打包项目

    第一步:打开maven Projects 第二步.找到package 第三步,运行.到路径下面去找打包的文件吧. 第二种方法: 使用命令 cmd进入项目目录,例如项目在D盘项目名poject 输入: ...

  5. sqoop 使用

    spark 环境搭建 下载解压 wget https://mirrors.tuna.tsinghua.edu.cn/apache/sqoop/1.4.7/sqoop-1.4.7.bin__hadoop ...

  6. windows server 2008 r2 负载平衡 找不到主机 解决方案

    在C:\Windows\System32\drivers\etc文件夹中的host文件里手工将主机名WIN-********解析至IP 即可.

  7. centos 6.8安装redis

    1. 下载到redis下载页面https://redis.io/download下载对应版本的reids安装包,如:redis-${version}.tar.gz . 2. 安装redis的详细安装步 ...

  8. js 操作对象 记录

    js 对象记录一下: let obj_1 = { name : 'james', age : '22', sex: '1' } for ( i in obj_1 ) { console.log(i) ...

  9. Java入门系列

    包装类 基本数据类型之间的相互转换不是都可以制动转换的,而你强制转换又会出问题,比如String类型的转换为int类型的,那么jdk为了方便用户就提供了相应的包装类. 基本类型对应的包装类 创建一个包 ...

  10. Andrew NG 机器学习编程作业3 Octave

    问题描述:使用逻辑回归(logistic regression)和神经网络(neural networks)识别手写的阿拉伯数字(0-9) 一.逻辑回归实现: 数据加载到octave中,如下图所示: ...