Hdu 6170 Two strings【思维+Dp】
来源:互联网 发布:数据分析工具有哪些 编辑:程序博客网 时间:2024/05/17 22:27
Two strings
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
The first string contains lowercase letters and uppercase letters.
The second string contains lowercase letters, uppercase letters, and special symbols: “.” and “*”.
. can match any letter, and * means the front character can appear any times. For example, “a.b” can match “acb” or “abb”, “a*” can match “a”, “aa” and even empty string. ( “*” will not appear in the front of the string, and there will not be two consecutive “*”.
For each test case, there are two lines implying the two strings (The length of the two strings is less than 2500).
3aaa*abba.*abbaab
yesyesno
题目大意:
给出两个字符串,第一个字符串只包含小写或者大写字母,第二个字符串包含小写或者大写字母或者特殊字符“.”和“*”,这里“.”可以替换为任意字符,但是不能变成空。
这里“a*”可以变成空串,可以变成a,也可以是aa,也可以是aaa,还可以是aaaa.以此类推,不限长度。
问第二个串和第一个串是否能够完全相等。
思路:
观察到数据范围,如果是贪心做法的话,数据范围肯定不能这么小,而且仔细考虑一下,直接贪心O(n)扫显然有纰漏;
那么我们考虑Dp,设定Dp【i】【j】表示串2到位子i,实际匹配串1到位子j的方案是否存在。
那么不难想到其状态转移方程:
①if(b[i]是大写字母或者是小写字母)Dp【i】【j】=Dp【i-1】【j-1】&&(a【i】==a【j】);
②if(b[i]是“.”)Dp【i】【j】=Dp【i-1】【j-1】;
③if(b[i]是“*”):
Dp【i】【j】=max(Dp【i-1】【j】,Dp【i】【j】);
Dp【i】【j】=max(Dp【i-2】【j】,Dp【i】【j】);
Dp【i】【j】=max(Dp【i-1】【k~j-1】,Dp【i】【j】);位子k到位子j-1之间的字符要保证都相等。
我们发现暴力去搞的话时间复杂度最坏可以达到O(n^3),那么我们考虑优化,很显然位子k是可以进行二分的,但是时间复杂度还是O(n^2logn)依然不低,但是我们可以维护一个数组pre【j】,表示和a【j】相等的字符串的最前边的位子,也就是我们的k,可以在Dp的过程维护,那么我们只要再求一个Dp的前缀和优化一下就能够达到O(n)了;那么状态转移方程③可以进行优化为:
Dp【i】【j】=max(Sum【i-1】【j-1】-Sum【i-1】,Dp【i】【j】);位子k到位子j-1之间的字符要保证都相等。
注意初始化,就没有别的什么了。
Ac代码:
#include<stdio.h>#include<string.h>#include<iostream>using namespace std;char a[2600];char b[2600];bool dp[2600][2600];int pre[2600];int Is_or[2600][2600];int main(){ int t; scanf("%d",&t); while(t--) { scanf("%s",a+1); scanf("%s",b+1); int n=strlen(a+1); int m=strlen(b+1); memset(dp,false,sizeof(dp)); dp[0][0]=true; for(int i=1;i<=m;i++) { for(int j=0;j<=n;j++) { if(j==1)pre[j]=j; else { if(a[j]==a[j-1])pre[j]=pre[j-1]; else pre[j]=j; } if(b[i]=='.') { if(j-1>=0)dp[i][j]=dp[i-1][j-1]; } else if(b[i]=='*') { if(j==0)dp[i][j]=dp[i-1][j]; else { int pos=pre[j]; int tmp; if(Is_or[i-1][j-1]-Is_or[i-1][pos-1]>0)tmp=1; else tmp=0; dp[i][j]=tmp; } if(i-1>=0)dp[i][j]=max(dp[i][j],dp[i-1][j]); if(i-2>=0)dp[i][j]=max(dp[i][j],dp[i-2][j]); } else { if(j-1>=0)dp[i][j]=(dp[i-1][j-1])&&(b[i]==a[j]); } if(j==0)Is_or[i][j]=dp[i][j]; else Is_or[i][j]=dp[i][j]+Is_or[i][j-1]; } } if(dp[m][n]==true)printf("yes\n"); else printf("no\n"); }}
- Hdu 6170 Two strings【思维+Dp】
- hdu 6170 Two strings dp
- hdu 6170 Two strings(DP)
- HDU 6170(Two strings-DP)
- hdu 6170 Two strings(dp)
- hdu 6170 Two strings dp模拟
- HDU 6170 Two strings (dp)
- HDU 6170 Two strings (二维DP)
- hdu 6170 Two strings(线性dp)
- HDU 6170 Two strings(dp)
- HDU 6170 Two strings dp || 正则
- hdu 6170 Two strings (dp)
- HDU 6170 Two strings (DP)
- HDU 6170 Two strings(DP)
- hdu 6170 Two strings
- HDU 6170:Two strings
- HDU 6170 Two strings
- hdu 6170 Two strings
- UI12-分段视图
- hdu 6170 Two strings dp模拟
- forEach 和 map 的区别
- 【转】jar包和war包的介绍和区别
- 晚餐
- Hdu 6170 Two strings【思维+Dp】
- sso单点登录,HTTP跳转HTTPS登录后回跳HTTP
- 适配器模式
- onvif协议框架搭建
- javascript实现把指定元素移动到第一位
- service httpd does not support chkconfig的问题
- 关于接口调用相关
- java之transient
- 在北京的思考