http://poj.org/problem?id=2533
 
题意:给你n(1-1000)个数,求这n个数的最长升序列。
 
题解:dp【i】表示以第i个数结尾的最长升序列。

#include <iostream>
#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <set>
using namespace std;
int v[] , w[] , dp[] , a[]; int main()
{
int n ;
while(cin >> n)
{
for(int i = ; i <= n ; i++)
{
cin >> a[i] ;
dp[i] = ;
}
for(int i = ; i <= n ; i++)
{
for(int j = ; j < i ; j++)
{
//dp[i]记录以i结尾的前i个最长上升子序列
if(a[j] < a[i]) // dp[j] 代表前j个子序列的最长上升子序列
{
dp[i] = max(dp[i] , dp[j] + ); // 如果第i个数大于第j个数,就在前j个最长子序列的个数上加一再比较
}
}
}
int max1 = ; // 注意不要认为dp[n]就是整个序列的最大子序列。他只是n为结尾的最大子序列
for(int i = ; i <= n ; i++)//例如 : 1 2 3 100 1 .这里的dp[n] = 1 ;
{
if(max1 < dp[i])
max1 = dp[i] ;
}
cout << max1 << endl ; } return ;
}

优化:另开一个数组dp该数组长度始终是进行到某点的最长长度,且该数组是递增的,但不一定是该序列的最长上升序列,例如:3 5 1 ,该数组为1 5。

该数组有两种操作:1、如果a【i】大于dp的最后一个元素,则直接加到dp数组末尾。

2、如果小于等于,对dp数组中的元素进行二分查找找到大于a[i]的下标,并将其替换。

note:lower_bound找到第一个大于等于a[i]的下标,upper_bound找到第一个大于a[i]的下标。

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF 0x3f3f3f3f
#define mod 1000000007
#define PI acos(-1)
using namespace std;
typedef long long ll ;
int a[];
int dp[]; int main()
{
/*#ifdef ONLINE_JUDGE
#else
freopen("D:/c++/in.txt", "r", stdin);
freopen("D:/c++/out.txt", "w", stdout);
#endif*/
int n ;
scanf("%d" , &n);
for(int i = ; i <= n ; i++)
{
scanf("%d" , &a[i]);
}
int l = ;
dp[l++] = a[];
for(int i = ; i <= n ; i++)
{
if(a[i] > dp[l-])
{
dp[l++] = a[i];
}
else{
int index = lower_bound(dp , dp+l , a[i]) - dp;//upper_bound找到第一个大于a【i】的下标,一样ac
dp[index] = a[i];
}
}
cout << l << endl ; return ;
}
//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF 0x3f3f3f3f
#define mod 1000000007
#define PI acos(-1)
using namespace std;
typedef long long ll ;
int a[];
int dp[]; int halfsearch(int *a , int len , int x)//upper_bound实现
{
int l = , r = len , mid = (l+r) >> ;
while(r >= l)
{
if(a[mid] > x)//目标在左边
{
r = mid - ;
}
if(a[mid] <= x)//不取等就TLE.
{
l = mid + ;
}
mid = (l + r) >> ;
}
return l ;
} int main()
{
/*#ifdef ONLINE_JUDGE
#else
freopen("D:/c++/in.txt", "r", stdin);
freopen("D:/c++/out.txt", "w", stdout);
#endif*/
int n ;
scanf("%d" , &n);
for(int i = ; i <= n ; i++)
{
scanf("%d" , &a[i]);
}
int l = ;
dp[l] = a[];
for(int i = ; i <= n ; i++)
{
if(a[i] > dp[l])
{
dp[++l] = a[i];
}
else{
int index = halfsearch(dp , l , a[i]);
dp[index] = a[i];
}
for(int i = ; i <= l ; i++)
{
cout << dp[i] << " ";
}
cout << endl ;
}
cout << l << endl ; return ;
}

题意:给你n个数,求一个序列的和最大,条件是该序列是递增的。

 
题解:跟最长子序列很像但有区别,区别就是最长子序列的和不一定是最大的。比如:1 100 2 3 4 . 最长子序列和为10 , 而答案应该是101.
该题求的是递增序列的最大和。不一定是最长。

#include <iostream>
#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <set>
using namespace std;
int v[] , w[] , dp[] , a[] ;
int len1 , len2 ; int main()
{
int n ;
while(~scanf("%d" , &n) && n )
{
for(int i = ; i <= n ; i++)
{
scanf("%d" , &a[i]);
dp[i] = a[i] ;
}
for(int i = ; i <= n ; i++)
{
for(int j = ; j <= i ; j++)
{
if(a[i] > a[j])
{
dp[i] = max(dp[i] , dp[j] + a[i]);//d[i]以i结尾的最大子序列和
}
}
}
int max1 = ;
for(int i = ; i <= n ; i++)
{
if(max1 < dp[i])
max1 = dp[i] ;
}
cout << max1 << endl ; } return ;
}
 

dp(最长升序列)的更多相关文章

  1. P1091 合唱队形 DP 最长升序列维护

    题目描述 NN位同学站成一排,音乐老师要请其中的(N-KN−K)位同学出列,使得剩下的KK位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,…,K1,2,…,K,他 ...

  2. dp(最长升序列:二分查找时间优化nlogn)

    We are all familiar with sorting algorithms: quick sort, merge sort, heap sort, insertion sort, sele ...

  3. 最长升序列 DP

    class Solution: def lengthOfLIS(self,nums): if not nums:return 0 #边界处理 dp = [1 for _ in range(len(nu ...

  4. P1020 导弹拦截 dp 树状数组维护最长升序列

    题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...

  5. (LIS)最长上升序列(DP+二分优化)

    求一个数列的最长上升序列 动态规划法:O(n^2) //DP int LIS(int a[], int n) { int DP[n]; int Cnt=-1; memset(DP, 0, sizeof ...

  6. XHXJ's LIS HDU - 4352 最长递增序列&数位dp

    代码+题解: 1 //题意: 2 //输出在区间[li,ri]中有多少个数是满足这个要求的:这个数的最长递增序列长度等于k 3 //注意是最长序列,可不是子串.子序列是不用紧挨着的 4 // 5 // ...

  7. uva103(最长递增序列,dag上的最长路)

    题目的意思是给定k个盒子,每个盒子的维度有n dimension 问最多有多少个盒子能够依次嵌套 但是这个嵌套的规则有点特殊,两个盒子,D = (d1,d2,...dn) ,E = (e1,e2... ...

  8. [LeetCode] Number of Longest Increasing Subsequence 最长递增序列的个数

    Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...

  9. 洛谷 P1020 导弹拦截(dp+最长上升子序列变形)

    传送门:Problem 1020 https://www.cnblogs.com/violet-acmer/p/9852294.html 讲解此题前,先谈谈何为最长上升子序列,以及求法: 一.相关概念 ...

随机推荐

  1. ES6——面向对象应用

    面向对象应用——React 特点:     1.组件化(模块化) --- class(一个组件就是一个class)     2.强依赖与JSX (JSX==babel==browser.js  是JS ...

  2. 行人重识别(ReID) ——技术实现及应用场景

    导读 跨镜追踪(Person Re-Identification,简称 ReID)技术是现在计算机视觉研究的热门方向,主要解决跨摄像头跨场景下行人的识别与检索.该技术能够根据行人的穿着.体态.发型等信 ...

  3. NLP 中 Attention Model 解析

    Attention Model,简称AM模型,本文只谈文本领域的AM模型,其实图片领域AM的机制也是相同的. 目前绝大多数文献中出现的AM模型是附着在Encoder-Decoder框架下的,但是其实A ...

  4. linux基础知识(三)

    添加用户 •useradd -d 家目录 -g 组名 -G 组集合(逗号间隔) -p 密码 -s 用户shell程序 用户名 •useradd -d /usr/local/nginx/ -g ngin ...

  5. ps:图层的选择

    接着我们建立一个名为nose的新层,颜色标记为蓝,画上一个扁椭圆形的鼻子,这样就算完成了一个简单人脸的绘制.此时在图层调板可以看到刚才所建立的所有图层.如下左图. 在图层调板中每个图层的最左边有一个眼 ...

  6. jmeter性能工具 使用手册(一)

    前置条件: 在jmeter官网下载jmter 安装包 电脑有java 环境 使用步骤: 打开jmeter 2.新建线程 Test plan--->add-->theads(users)-- ...

  7. LeetCode--043--字符串相乘(java)

    给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式. 示例 1: 输入: num1 = "2", num ...

  8. vscode中执行gulp task的简便方法

    本文重点是gulp在vscode中执行task任务的方法 如何像webstorm那样简便操作gulp 的task 第1步:安装node.下载地址:https://nodejs.org/zh-cn/ 检 ...

  9. vue中的render函数介绍

    简介:对于不了解slot的用法(参考:大白话vue-slot的用法)又刚接触render函数的同学来说,官网的解释无疑一脸懵逼,这里就整理下个人对render函数的理解 问题: 1.render函数是 ...

  10. RSS(简易信息聚合)和jieba(第三方分词组件)

    简易信息聚合(也叫聚合内容)是一种RSS基于XML标准,在互联网上被广泛采用的内容包装和投递协议.RSS(Really Simple Syndication)是一种描述和同步网站的内容格式,是使用最广 ...