PAT 1045. Favorite Color Stripe

有点动态规划的意思。

假设Eva最喜欢的颜色分别为favor[0]、favor[1]、favor[2]……favor[m-1],而给定的序列为shu[0]、shu[1]、shu[2]……shu[n-1]。(题目里说颜色有n种,那个n没用的,所以我还是习惯性地在代码里把序列长度叫做n)

我们可以先有这样一个大体的思路:“根据后面的,往前面推算”,在给定序列的第i位,也就是shu[i],如果我们已经知道序列的(i+1)——(n-1)最长可以凑出长为len的串,那我们只需要判断一下shu[i]本身,如果shu[i]能放在那个长为len的串前面,那么序列的i——(n-1)位最长能凑出len+1串;否则,序列的i——(n-1)位最长只能凑出长为len的串。

所以,整个过程是从后往前处理的,最后我们会得出序列的第0——(n-1)位最长能凑出多长的串,也就是题目的答案了。

现在要考虑的是,怎么判断shu[i]本身呢?怎么知道它能不能放在已有串的前面呢?何况“已有最长串”也不是唯一的呀。

解决方法是,把这种“从后往前”的处理操作m次,每次“从后往前”都是针对具体的一种颜色来的,第一次,遍历的时候要判断每个shu[i]是否等于favor[m-1],是的话说明串串可以加一了,这样按前面讲的思路,这一遍下来,我们就知道i——(n-1)位 能凑出的、仅含favor[m-1]的最大串长是多少(i=0,1,2……(n-1))。

第二遍,遍历的时候判断shu[i]是否等于favor[m-2],是的话可以加一,因为,显然,已有的串是 只含favor[m-1] 或 只含favor[m-1]和favor[m-2]两种颜色的,所以加一不会有颜色顺序不对的问题。所以尽管解有可能不唯一,我们还是只需计算、保存这个长度即可,这个长度一定是正确的。

第三遍……第四遍……第m遍。输出最终结果。

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int kind;
int favor[205],m;
int shu[10005],n;
int most[10005];
int main(){
	int i;
	scanf("%d",&kind);
	scanf("%d",&m);
	for(i=0;i<m;i++){
		scanf("%d",&favor[i]);
	}
	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%d",&shu[i]);
		
	memset(most,0,sizeof(most));
	int j;
	for(j=m-1;j>=0;j--){
		for(i=n-1;i>=0;i--){
			if(shu[i]==favor[j]){
				if(most[i+1]+1>most[i])
					most[i]=most[i+1]+1;
			}
			else{
				if(most[i+1]>most[i])
					most[i]=most[i+1];
			}
		}
	}
	printf("%d\n",most[0]);
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值