【PAT甲级】1045 Favorite Color Stripe (30分)

解题过程的小记录,如有错误欢迎指出。

难度:三星(最长递增序列的变形题,最后两个测试点数据量较大,用set会超时,用邻接矩阵可以)

题目分析

给出一串数列,要求找出最长的按照指定的增减顺序的子序列

注意点

  1. 最后两个测试点的数据量较大,要选择采用省时的方法

我的解题过程

思路

  1. 因为本题的总颜色数不超过200个,所以用邻接矩阵pre[i][j]保存颜色i前面可以连着的颜色j,数组类型为bool,当前面可以存在某数时为true
  2. 然后就是套的最长递增数列的模板,用dp[i]记录以i结尾的最长序列,ans保存最长序列长度

bug

  1. 用set设置每个颜色的前驱数组,然后在后面查找最长序列的时候用find进行判断,有两个测试点会超时

代码

#include<iostream>
#include<algorithm>

using namespace std;

const int MAXN = 205;
int dp[10005], order[MAXN];
bool pre[MAXN][MAXN];

int main()
{
	int n;
	scanf("%d", &n);
	int m;
	scanf("%d", &m);
	for (int i = 1; i <= m; i++) {
		scanf("%d", &order[i]);
	}
	fill(pre[0], pre[0] + MAXN*MAXN, false);
	for (int i = 1; i <= m; i++) {
		for (int j = 1; j <= i; j++) {
			pre[order[i]][order[j]] = true;
		}
	}
	int L[10005];
	int length;
	scanf("%d", &length);
	for (int i = 1; i <= length; i++) {
		scanf("%d", &L[i]);
	}
	int ans = 0;
	for (int i = 1; i <= length; i++) {
		dp[i] = 1;
		for (int j = 1; j < i; j++) {
			if (pre[L[i]][L[j]]==true && dp[i] < dp[j] + 1) {
				dp[i] = dp[j] + 1;
			}
		}
		ans = max(ans, dp[i]);
	}
	printf("%d", ans);
    return 0;
}

dalao的代码

全部代码因版权原因不放出来,大家可以自行去柳神博客购买或者参考晴神的上机笔记~

借鉴点

  1. 建议参考一下算法笔记上对应章节的模板
  2. 可以采用映射将不单调递增的序列映射到hash表上就边成了单调递增序列
  3. 因为L的长度较大,如果要做时间上的优化可以把L数组中不是Eva喜欢的颜色给直接去掉,这样L的长度会缩短,在进行为dp赋值的时候节省时间
  4. 本题可以去看一下上机宝典的对应章节,做法值得参考(不愧是30分的题orz)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值