【洛谷】P1470 最长前缀 Longest Prefix----动态规划DP

26 篇文章 0 订阅

题目链接:https://www.luogu.org/problemnew/show/P1470

这道题就是类似完全背包和N^2的LIS的思想,如果连背包和LIS都没学过的可以百度DD大牛的背包9讲和LIS,都是很经典的DP模型,再回来看这题应该就能迎刃而解了。  

然后再掌握了基本背包思想后回到来看这一题的思路,就是先把所以的模式串P都存起来,之后我们逐个对i位置尝试该位置能不能放任意一个模式串,能的话就把dp[i]标记为1,当然还要先查看dp[i-模式串长度]为不为1,如果你前面都匹配不上了,后面这里匹配上了也没有用,毕竟要找的是最长连续能匹配的。  

已经很多大佬把思路讲的很好了,这里就是随便再写写,代码也自认还算清晰,然后主要发这篇文章的原因是想提醒大家注意两个坑点,第一个就是边界问题,这里i的边界是需要<=而不是<字符串长度的,第一次习惯性没加=然后一个数据WA了(这里自行思考一下为什么,应该是很简单的)。  

第二个坑点跟这题无关,算C++方面的,就是size_type类型跟int类型做运算后要强制类型转换,不如会出现奇怪的BUG,例如我第一次没做强制类型转换就发现if怎么样都能进去,输出又是正确的(因为输出时的%d也算做了转换)


下面附上一下AC代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<set> 
using namespace std;
set<string> p;
int dp[200005]={0};
int main()
{
	ios::sync_with_stdio(false);
	string pi;
	while(cin>>pi&&pi!=".")
	{
		p.insert(pi);
	}
	string s;
	while(cin>>pi)
	{
		s+=pi;
	}
	dp[0]=1;
	//注意i的边界是<=size() 
	for(int i=1;i<=s.size();i++)//理论上来说这里的size()最好也先取出来,一是省常数时间,二是避免玄学BUG 
	{
		for(set<string>::iterator it=p.begin();it!=p.end();it++)
		{
			string tmp=(*it);	
			if((int)(i-tmp.size())>=0)//size_type类型做运算要强制转换,以免出现玄学BUG 
			{
				if(dp[i-tmp.size()]&&tmp==s.substr(i-tmp.size(),tmp.size()))//类完全背包思想 
				{
					dp[i]=1;
				}
			}
		}
	}
	//注意i的边界是=size() 
	for(int i=s.size();i>=0;i--)
	{
		if(dp[i])
		{
			printf("%d",i);
			return 0;
		}
			
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值