POJ 1836 Alignment 最长上升(下降)子序列(dp)
来源:互联网 发布:首席数据师by徐徐图之 编辑:程序博客网 时间:2024/04/27 16:17
题目链接:Alignment
题目大意:给出一串士兵的身高,现在要求每个士兵都能一眼看到最左边或最右边,因此需要一些士兵出列,问最少要有多少士兵出列。
因为士兵看到最左边或者最右边都是可以的,因此我们只要求出每个位置左边最多能留下多少人和每个位置右边最多能留下多少人,对每个位置,记录下最多左边留下多少人,然后在右面的序列中找出一个能在右面留下最多人的位置,两者加和,然后遍历所有的位置,找出最大的和,就是最多能留下多少人,用总人数减去留下的人,就是题目要求的最少出列的人数。
(又见灵魂画风)(数据来自Discuss)
如图,黑字为高度,蓝字为从左到右的最长上升子序列长度,红字为由右到左的最长上升子序列长度(也就是从左到右的最长下降序列长度),这组数据,观察可知,当第四和第五个位置的士兵,也就是高度为1和2的士兵出列后,就可以形成一个符合题目要求的序列,因此这组数据答案为2。由左到右的最高的是第三位的5,由右到左最高的是第六位的5.
那么,在代码中,我们要如何实现这个查找呢,很简单,只要求出每个位置的最长上升子序列长度和最长下降子序列长度,然后把每一个位置当做由左到右的最高的位置,然后向右边找由右到左最高的,也就是最长下降子序列长度最大的,两者相加得出的就是当前位置为由左到右最高的时候队列中可以留下多少士兵,然后遍历每个位置,找到这个过程中的最大值即可。这个最大值就是最终的结果。
这里要继续吐槽POJ的数据,网上搜的题解,有相当一部分其实代码是错的,但是因为POJ的数据太水,导致了他们也通过了这个题。而且POJ的玄学问题,确实是很多......
还是最后放代码:
#include <stdio.h>#define Max(x,y) x>y?x:yint main(){int n, i, l, ans = 0;int up[1111], down[1111];double h[1111];scanf("%d", &n);for (i = 1; i <= n; i++)scanf("%lf", &h[i]);for (i = 1; i <= n; i++)//求出每个位置的最长上升子序列长度{up[i] = 1;for (j = 1; j < i; j++)if (h[i] > h[j])up[i] = Max(up[i], up[j]+1);}for (i = n; i >= 1; i--)//求出每个位置的最长下降子序列长度{down[i] = 1;for (j = i + 1; j <= n; j++)if (h[i] > h[j])down[i] = Max(down[i], down[j]+1);}for (i = 1; i < n; i++)//遍历每个位置作为第一部分终点的情况for (j = i + 1; j <= n; j++)//遍历第一部分终点后的每个位置,找到答案最大的第二部分的起点ans = Max(ans, up[i]+down[j]);printf("%d\n", n-ans);//总人数减去留下的人数就是需要出列的人数return 0;}照例代码中有编译错误,一个简单的防爬虫,请见谅。
- POJ 1836 Alignment(DP max(最长上升子序列 + 最长下降子序列))
- poj 1836 Alignment -dp(合唱队形变式)-最长上升子序列+最长下降子序列
- poj 1836 Alignment( 最长上升(下降)子序列 )
- POJ 1836 Alignment 【最长上升(下降)子序列】
- POJ 1836 Alignment 最长上升(下降)子序列(dp)
- POJ 1836Alignment(DP最长上升子序列)
- POJ 1836 Alignment (最长上升 下降子序列)
- POJ 1836 Alignment LIS变形(最长上升子序列)
- [poj 1836] Alignment 最长上升子序列
- poj 1836 Alignment(最长上升子序列)
- (POJ1836)Alignment <DP,最长上升子序列变形>
- poj-1836 最长上升/下降子序列
- POJ1836-Alignment(最长上升子序列)
- poj 1836 Alignment (最长上升子序列 N*log(n))@
- POJ-1836 Alignment (Romania OI 2002 线性dp 最长上升子序列)
- 【最长下降子序列+有难度】北大 poj 1836 Alignment
- DP---最长上升/下降子序列
- poj_1836 Alignment(最长上升子序列+枚举)
- java---java的序列化问题
- arm linux 文件系统制作
- 推导大O阶方法
- iOS Rumtime 之关联引用
- Leetcode 300. Longest Increasing Subsequence (Medium) (cpp)
- POJ 1836 Alignment 最长上升(下降)子序列(dp)
- R语言实战 chapter2
- swift中的协议(get,set)介绍
- 牛客网刷题笔记--剑指offer(数据流中的中位数)
- wingide的使用方法积累
- sql随机获获取数据
- 30行代码实现Javascript中的MVC
- javascript省份证验证
- [code generation] Freemarker官网文档_What is Apache FreeMarker?