poj-1836 最长上升/下降子序列
来源:互联网 发布:淘宝捉猫猫是干什么的 编辑:程序博客网 时间:2024/04/27 18:24
Alignment
题意:输入一串数字代表着一列排好队的军人的身高,现在要求从其中移走一些人,使得剩余在队伍中的任何一个人都可以向左或者向右看到队伍的头。队伍中身高并列最高的几个人不会相互阻碍,但是其余的身高相同的人会相互阻碍视线,求最少要移出多少人才能满足要求。
首先理解一下题意,抛开背景,题目要求在一列数中移出最少的数,使得从左到右先是递增,到一个顶点后一直递减。最大的顶点可以连续有几个相同大小的,其余的数必严格递增或者递减。这样,我们可以把题目转化为最长上升/下降子序列来处理,将上升和下降的过程分两次来做。组合后找出最长的先上升后下降的序列,答案就是用原队伍人数减去最长先上升后下降子序列长度。(需要考虑只递增无递减或者只递减无递增的情况)
首先理解一下题意,抛开背景,题目要求在一列数中移出最少的数,使得从左到右先是递增,到一个顶点后一直递减。最大的顶点可以连续有几个相同大小的,其余的数必严格递增或者递减。这样,我们可以把题目转化为最长上升/下降子序列来处理,将上升和下降的过程分两次来做。组合后找出最长的先上升后下降的序列,答案就是用原队伍人数减去最长先上升后下降子序列长度。(需要考虑只递增无递减或者只递减无递增的情况)
先来求最长上升序列。a[i]表示第i个数的大小。用b[i]表示第i个数作为最大值时,最长上升序列数量是多少。则b[i+1]值为1~j(1<=j<=i)数里小于a[i+1]且b[i]值最大的数加一。表示为 b[i] = MAX(b[1~j])+1,(j<i,a[i]>a[j])。代码如下:
b[1]=1;for(int i=2;i<=n;i++){int max = 1;for(int j=1;j<i;j++){if(a[i]>a[j]&&b[j]+1>max){max = b[j]+1;}}b[i]=max;}
求最长下降子序列的方法类似,只是求解过程相反,从右向左求最长上升子序列。c[i]表示以第i个数表示最大值时,最长下降子序列的数量。代码如下:
c[n]=1;for(int i=n-1;i>=1;i--){int max = 1;for(int j=n;j>i;j--){if(a[i]>a[j] && c[j]+1>max){max = c[j]+1;}}c[i]=max;}
现在我们已知了以各点作为顶点的最长上升/下降子序列。以i表示上升序列中最高的点,j表示下降序列中最高的点,由于可以最高点可以有数个相同大小的,所以i和j可能不相同。循环判断各种和j组合i的情况,找出最大值。代码如下:
int num=0;int max=0;for(int i=1;i<=n;i++){for(int j=i;j<=n;j++){if(a[i]==a[j]){num = b[i]+c[j];if(i==j){num--;}if(num>max){max = num;}}}}
下面是我AC的完整代码:
#include<iostream>#include<math.h>using namespace std;int n;float a[1010],b[1010],c[1010];int dp[1010][1010];int main(){cin >> n;for(int i=1;i<=n;i++){cin >> a[i];}b[1]=1;for(int i=2;i<=n;i++){int max = 1;for(int j=1;j<i;j++){if(a[i]>a[j]&&b[j]+1>max){max = b[j]+1;}}b[i]=max;}c[n]=1;for(int i=n-1;i>=1;i--){int max = 1;for(int j=n;j>i;j--){if(a[i]>a[j] && c[j]+1>max){max = c[j]+1;}}c[i]=max;}int num=0;int max=0;for(int i=1;i<=n;i++){for(int j=i;j<=n;j++){if(a[i]==a[j]){num = b[i]+c[j];if(i==j){num--;}if(num>max){max = num;}}}}cout << n-max << endl;return 0;}
阅读全文
0 0
- poj-1836 最长上升/下降子序列
- poj 1836 Alignment( 最长上升(下降)子序列 )
- POJ 1836 Alignment 【最长上升(下降)子序列】
- POJ 1836 Alignment (最长上升 下降子序列)
- POJ 1836 Alignment(DP max(最长上升子序列 + 最长下降子序列))
- poj 1836 Alignment -dp(合唱队形变式)-最长上升子序列+最长下降子序列
- 最长上升下降子序列
- POJ 1836 Alignment 最长上升(下降)子序列(dp)
- [poj 1836] Alignment 最长上升子序列
- poj 1836 Alignment(最长上升子序列)
- 算法:最长上升下降子序列
- 最长上升(下降)子序列 O(nlogn)
- hdu4604 最长上升,下降子序列nlogn
- DP---最长上升/下降子序列
- BZOJ1046(HAOI2007)[上升序列]--最长下降子序列预处理
- poj 1836 (动态规划之最长上升子序列)
- POJ 1836Alignment(DP最长上升子序列)
- POJ 1836 Alignment LIS变形(最长上升子序列)
- sqlserver导出CVS文件换行
- LeetCode: 463. Island Perimeter
- BP算法公式推导
- Docker 快速入门指引及相关概念知识概览
- GPU通用计算API的变迁和趋势
- poj-1836 最长上升/下降子序列
- Mac 系统 git上传项目至gitHub
- Codeforces 340D Bubble Sort Graph【LIS变形】
- 一个简单趣味的pc-react站
- 获取自动增长主键的值
- CF822C:Hacker, pack your bags!(思维)
- 寻找第二小的数
- 机器人的洪流:刷库、撞库那些事儿
- 交叉编译libxml2的arm-linux库