PAT 甲级 A1045

题目连接

1045 Favorite Color Stripe (30分)

题目大意

给定一个Eva喜欢的颜色序列和一个总的颜色序列,从总的颜色序列中找出按Eva喜欢的颜色序列顺序出现的最长子序列。有点绕,结合样例来说明什么意思。假设Eva喜欢的颜色序列为 {2 3 1 5 6},总的颜色序列为{2 2 4 1 5 5 6 3 1 1 5 6}.那么需要从总的颜色序列中找出符合题意的序列有 {2 2 1 1 1 5 6}, {2 2 1 5 5 5 6}, {2 2 1 5 5 6 6}, {2 2 3 1 1 5 6}.
其中第一个序列按照2 1 5 6的顺序出现,满足。
第二,三个序列按照 2 1 5 6的顺序出现,满足。
第四个序列按照2 3 1 5 6的顺序出现,满足。

思路

用动态规划实现即可,dp[c]表示以颜色c结尾的序列长度,设dp[j]表示以颜色j结尾的序列长度,那么状态转移方程可以表示为:

dp[c] = max(dp[j]+1,dp[c]);

为了保证dp[j]表示的是dp[c]更新之前的长度,这里设置了temp来表示dp[c]未更新前的最长序列长度,所以状态转移方程为:

dp[c] = max(temp[j]+1,dp[c]);

另外,Eva喜欢的颜色的出现顺序,可以用一个数组w来表示。由于总的颜色序列中不一定含有Eva所喜欢的颜色,所以在执行状态转移方程前,需要简单地判断一下。所以就很容易地写出了下面的代码。

总的来说,程序的时间复杂度为O(nm),其中m为颜色的总数(给的最大为200)。

AC代码

#include<iostream>
#define maxn 10010
#define maxc 205
using namespace std;
int n, m, l, ans = 0;
int w[maxc];
int dp[maxc],temp[maxc];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
	int c;
	cin >> n >> m;        //n没什么卵用
	for (int i = 1; i <= m; i++) {
		cin >> c;
		w[c] = i;
	}
	cin >> l;
	for (int i = 0; i < l; i++) {
		cin >> c;
		if (!w[c]) continue;
		for (int j = 0; j < maxc; j++) {
			if (!w[j] ||w[j] > w[c]) continue;
			dp[c] = max(dp[c], temp[j] + 1);
		}
		dp[c] = max(1, dp[c]);
		ans = max(dp[c], ans);
		for (int j = 0; j < maxc; j++) { //temp记录了上次的dp
			temp[j] = dp[j];
		}
	}
	cout << ans;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值