Letter - 每天一把CF - 20201108

2020-11-08

dp

180C 1400

题目

原题链接:https://codeforces.com/problemset/problem/180/C

在这里插入图片描述

思路

题目大意:给定一个由大写和小写字母组成的字符串,字符串长度不超过1e5,现在有一操作,可以将其中任一字母的大小写改变,问要将这个字符串变成所有大写字母都在小写字母的前面的最小操作数,即先大写字母再小写字母(隐含了说也可以全大写字母或全小写字母)。

思路:唯一一道我可以说tjdl的题目,泪目

好好看看题目,明显跟具体的字母是什么没有关系,只跟其是大写或者小写有关系。

最后要我们得到的结果是先大写字母再小写字母,思考若把所以大写字母置为0,小写字母置为1,则要我们变得是一个非递减数列。

好了,问题很明显了,改变一个由0和1数组的一些项,使这个数组变成一个非递减数列。

看到这里,明显,是要我们求这个数组的最长非递减子序列的长度了,然后答案应该就是数组长度减去这个长度了。

然后,你就会TLE。。。。

n的范围是1e5,而最正宗的最长非递减子序列的复杂度是n^2,必炸无疑。

再次思考,当我们当前拿到一个0,与其满足非递减子序列的前一个状态的也一定是0的状态。

当我们拿到一个1时,其前一个状态就可以是0或者1了,看谁大就好了。

然后的然后,注意到,可能的状态只有两个,是确定的!!!!!

可以祭出字典大法了,我们记录到当前这个点为止,其前面最大的0的状态的dp值和1的状态的dp值。

所以复杂度由n^2降为n:

		for (int i = 1; i <= len; i++) {
   
			dp[i] = 1;
			if (a[i] == 0)
				dp[i] = mp[0] + 1;
			
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值