mirror of
https://github.com/xlucn/PAT.git
synced 2026-10-03 00:23:15 +08:00
add a1045
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
---
|
||||
layout: post
|
||||
date: 2021-03-29 00:23:37 +0800
|
||||
title: "PAT Advanced 1045. Favorite Color Stripe (30) (C语言实现)"
|
||||
categories: Advanced
|
||||
tags: [monotonic sub-list]
|
||||
permalink: Advanced/1045.html
|
||||
---
|
||||
|
||||
## 题目
|
||||
|
||||
{% include_relative html/a1045.md %}
|
||||
|
||||
## 思路
|
||||
|
||||
{% include_relative analysis/a1045.md %}
|
||||
|
||||
## 代码
|
||||
|
||||
[Github最新代码](https://github.com/OliverLew/PAT/blob/master/PATAdvanced/1045.c),欢迎交流
|
||||
|
||||
```c
|
||||
{% raw %}#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int N, M, L, c, order_to_color[200] = {0}, color_to_order[200] = {0};
|
||||
int longest_for_color[200] = {0}, longest_before_current, max_length = 0;
|
||||
|
||||
/* read number of different colors */
|
||||
scanf("%d", &N);
|
||||
/* read color-order pairs (colors start from 0, orders start from 1) */
|
||||
scanf("%d", &M);
|
||||
for(int i = M; i > 0; i--)
|
||||
{
|
||||
scanf("%d", &c);
|
||||
order_to_color[i] = --c;
|
||||
color_to_order[c] = i;
|
||||
}
|
||||
/* read color list */
|
||||
scanf("%d", &L);
|
||||
for(int i = 0; i < L; i++)
|
||||
{
|
||||
scanf("%d", &c);
|
||||
/* this color is not in the favourite list, do nothing */
|
||||
if(color_to_order[--c] == 0)
|
||||
continue;
|
||||
/* for colors of higher/equal order, find the longest sub-stripe */
|
||||
longest_before_current = 0;
|
||||
for(int j = M; j >= color_to_order[c]; j--)
|
||||
if(longest_before_current < longest_for_color[order_to_color[j]])
|
||||
longest_before_current = longest_for_color[order_to_color[j]];
|
||||
/* after this color, the length increases by 1 */
|
||||
longest_for_color[c] = longest_before_current + 1;
|
||||
}
|
||||
|
||||
for(int i = 0; i < N; i++)
|
||||
if(max_length < longest_for_color[i])
|
||||
max_length = longest_for_color[i];
|
||||
printf("%d\n", max_length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
{% endraw %}```
|
||||
@@ -0,0 +1,23 @@
|
||||
<!--
|
||||
2021-03-29 00:23:37 +0800
|
||||
monotonic sub-list
|
||||
-->
|
||||
|
||||
这道题的大意即给出了一组颜色的排序,在一长串颜色中按该顺序选取其中一个子数列。
|
||||
|
||||
其实,颜色的数字大小并无意义,如果将所给颜色重新映射为颜色的排名,对于题目的例子,即`2->5, 3->4, 1->3, 5->2, 6->1, 4->0`(不在喜爱颜色里的,如4,就映射为0),那么相当于**在一个数组里找出最长非递减子列**。上面这句话是最重要的,是最重要的,是最重要的。
|
||||
|
||||
我比较笨,好长时间都想不出一个快速的方法,终于一天开窍了。这个思路是一遍过的,随时得到目前已读数据的最终解,空间复杂度O(N),时间复杂度O(LN)。
|
||||
|
||||
打了很多字,感觉还是说的少一点,更容易理解,所以一句话:
|
||||
|
||||
**截至某个元素的最长非递减子列长度,等于它之前截至排名更高的任何颜色(注意不是任何元素)的最长非递减子列长度+1。**
|
||||
|
||||
伪代码:
|
||||
|
||||
- 读取N和M个喜爱颜色,排序
|
||||
- 初始化截止于每一个颜色的最长非递减子列长度为0
|
||||
- 读取L个颜色,对每一个颜色
|
||||
- 遍历排名高于或等于该颜色的所有颜色,找出子列长度的最大值
|
||||
- 将该颜色的最长子列长度更新为上述最长长度+1
|
||||
- 遍历所有颜色,输出子列最长者
|
||||
Reference in New Issue
Block a user