数塔问题和最长上升子序列问题
1.数字三角形问题
题意:给定一个数字三角形,从最上面出发往下走,每次只能走左下或者右下,求所有路径中最大的和。
分析:形状就跟杨辉三角形一样,那么,设原数组为a[][],设从底边到第i行第j列所走的路径中最大和为dp[i][j]。
那么,很明显有dp[i][j] = max(dp[i+1][j],dp[i+1][j+1]) + a[i][j];
2.最长上升子序列问题
分析:对于一个数列a[]来说,我们用dp[i]来表示以a[i]结尾的序列的最长上升子序列,那么假设现在我们知道了i之前的所
有dp[j],其中0<=j<i,那么状态转移方程为:dp[i] = max(dp[i],dp[j] + 1) ,0<=j<i,a[j]<a[i]。本算法的时间
复杂度为O(n^2)。
int Work(int a[],int n)
{
int ans = -1;
for(int i=0;i<n;i++)
dp[i] = 1;
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(a[i] > a[j])
dp[i] = max(dp[i],dp[j] + 1);
}
ans = max(ans,dp[i]);
}
return ans;
}
其实还有O(nlog(n))的算法。现在来介绍一下:
根据dp[]的值进行分类。对于dp[]的每一个取值k,我们只需要保留满足dp[t] = k的所有a[t]中的最小值。设d[k]记录这个值,即d[k] = min{a[t]} (dp[t] = k)。
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int N = 100005;
const int INF = ~0U>>1;
int a[N],d[N];
int Binary_Search(int l,int r,int x)
{
while(l < r)
{
int m = (l + r) >> 1;
/** 非严格上升子序列,如果是严格上升子序列,应该把下面的<=改为<即可 */
if(x <= d[m]) r = m;
else l = m + 1;
}
return l;
}
int Work(int a[],int n)
{
d[0] = -1;
int max = -1;
int len = 1;
for(int i=1;i<=n;i++)
{
d[len] = INF;
int j = Binary_Search(0,len,a[i]);
if(j == len) len++;
d[j] = a[i];
}
return len - 1;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
printf("%d\n",Work(a,n));
}
return 0;
}
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1087
题意:给定一个序列a[],求这个序列的子序列中和最大的值。
分析:这个题比较有意思,跟最长上升子序列相比,不同点是最长上升子序列求的是上升长度最大值,而本题是求上升的和最
大值,那么可以类比。我们知道在最长上升子序列中的状态转移方程是:dp[i] = max(dp[i],f[j] + 1),0<=j<i,a[j]<a[i]。
那么对于和同样的思路得到:dp[i] = max(dp[i],dp[j] + a[i]),0<=j<i,a[j]<a[i]。
int Work(int a[],int n)
{
int ans = -1;
for(int i=0;i<n;i++)
dp[i] = a[i];
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(a[i] > a[j])
dp[i] = max(dp[i],dp[j] + a[i]);
}
ans = max(ans,dp[i]);
}
return ans;
}
数塔问题和最长上升子序列问题相关推荐
- 模板 - 最长上升子序列与最长公共子序列
整理的算法模板合集: ACM模板 目录 1.最长上升子序列(LIS) 1.1树状数组优化O(nlogn)O(nlogn)O(nlogn) 2.最长公共子序列(LCS) 2.1转换成LIS优化O(nlo ...
- 最长上升子序列(LIS)/最长不上升子序列问题算法详解+例题(树状数组/二分优化,看不懂你来打我)
目录 最长上升子序列 一.朴素做法O(2n)O(2^n)O(2n) 二.优化做法O(nlogn)O(nlogn)O(nlogn) 三.例题引入:P1020 导弹拦截(求最长上升子序列和最长不上升子序列 ...
- 2018.01.01(数字三角形,最长上升子序列等)
2017.12.24 简单的动态规划 1.数字三角形(算法引入) 题目描述:下图所示是一个数字三角形,其中三角形中的数值为正整数,现规定从最顶层往下走到最底层,每一步可沿左斜线向下或右斜线向下走.设 ...
- 动态规划应用--最长递增子序列 LeetCode 300
文章目录 1. 问题描述 2. 解题思路 2.1 动态规划 2.2 二分查找 1. 问题描述 有一个数字序列包含n个不同的数字,如何求出这个序列中的最长递增子序列长度?比如2,9,3,6,5,1,7这 ...
- 算法.动态规划 导航/数塔取数字问题
目录 前言 从1+1开始 总结下概念 地图到图 回头看 代码 动态规划经典问题 前言 下面的概念和公式可能会吓到你,看不懂没关系,就是让你恶心的.反正我看着也挺恶心,专业就是让你看不懂,看懂了怎么能叫 ...
- 都能看懂的LIS(最长上升子序列)问题
LIS问题介绍: 首先来说一下什么是LIS问题: 有一个长为n的数列a0, a1, ......, a(n-1).请求出这个序列中最长的上升子序列的长度.上升子序列指的是对于任意的i<j都满足a ...
- 最长公共子序列(LCS)问题算法详解+例题(转换成LIS,优化为O(nlogn),看不懂你来打我)
目录 最长公共子序列(LCS)问题 1.朴素做法 O(n2)O(n^2)O(n2) 2.转换成LIS优化O(nlogn)O(nlogn)O(nlogn) 3.P2758 编辑距离 最长公共子序列(LC ...
- LCS最长公共子序列和LIS最长上升子序列——例题剖析
一.LCS最长公共子序列 最长公共子序列(LCS)问题算法详解+例题(转换成LIS,优化为O(nlogn),看不懂你来打我) longest comment subsequence 模板题 longe ...
- 9.65 最长上升子序列
最长上升子序列 动态规划(朴素板) 以 a[i] 为结尾的最长上升子序列为 f[i] 复杂度 O(n^2) #include<iostream> using namespace std; ...
最新文章
- SharePoint 2013 搭建负载均衡(NLB)
- VC++ error C2248: “CObject::CObject”: 无法访问 private 成员(在“CObject”类中声明)
- boost::mpl模块实现push_back相关的测试程序
- Mybatisplus 自动生成字段 强制覆盖 null或者空字符串也覆盖
- 眉骨高者为大贵之相_男人此处“高大”,大富大贵,前途不可限量!!
- CANOpen紧急报文
- Python基础(函数)
- Linux学习12—文件服务
- View 的测量 MeasureSpec
- 春考计算机组装与维护,计算机组装与维护教程(高职高专计算机系列)
- 【产品】业务流程+任务流程+页面流程绘制指南
- 生活中笔记本内存的主要作用
- 隐藏input的三种方法和区别
- 白杨SEO对话老姜:聊聊第三方平台站内SEO,第三方平台的引流的逻辑是什么?
- 如何利用SFTP在远程服务器中保障文件传输安全
- Python函数命名-PEP8编码规范的说明及IDE提示的忽略
- FFMPEG:SPS和PPS
- MDCC王戈点爆全场:Smule乐器王是怎样炼成的
- C# WMI之Win32_IP4RouteTable
- boost C++知识点(一)