HDU
来源:互联网 发布:s7300模拟量编程 编辑:程序博客网 时间:2024/06/02 02:44
题目大意:
有两个字符串 a、b,a字符串由大写字母和小写字母组成,b字符串除了大写字母和小写字母还有‘ * ’和‘.’。‘.’表示该字符可以变成任意字符,‘ * ’表示该字符的前一个字符可以变成任意多个,包括0个。现在问你,对于给定的两个字符串,是否可以通过对b字符串特殊字符的变换使得a字符串和b字符串完全相同。
分析:
首先假设对于两个字符串,只要不出现 ” .* “的情况,我都是可以以一种贪心的策略判断是不是能匹配的。但是因为 ” .* ” 的出现,就导致了选择的多样性,也就是说,此时,在不知道后面字符的情况下,你就没办法保证你当前的选择一定是最优的了。于是就想到了动态规划。
dp建立:
确定状态:
状态转移方程:
因为这个状态转移方程不好写成一个表达式,所以就用口头叙述转移过程了。
首先,外层循环 i ,内层循环 j 。对于每个 i :
1.如果 b[ i ] 为 * ,就跳过进行下一个 i 。
2.如果 b[ i ] 不为 * ,那么就看 b[ i+1 ] 是否为 * 。
(1)如果 b[ i+1 ] 不为 * ,那么如果 dp[ i+1 ] [ j+1 ] ==1,并且a[ j ] == b[ i ] ,那么就能匹配,否则不能。
(2)如果 b[ i+1 ] 为 * ,那么,如果 dp[ i+2 ] [ j ] ==1,就能匹配。同时从 a[ j ] 开始,向前找连续的 a[ j-k ] == b[ i ] ,这些对应的dp都直接赋值为1,直到遇到一个不相等的才停止。注:如果是 “.”,就先把它赋值成 a[ j-1 ] 然后再用上述方法匹配。
确定边界条件:
这个边界条件就是打代码的时候特别难确定的。我选择的是确定b数组里哪些可以变成空,然后这些 dp[ i ][ n ]=1 表示可以和 0 个 a 字符串里的字符匹配。
代码:
#include<bits/stdc++.h>#define maxn 2550using namespace std;int test;char a[maxn],b[maxn];bool com[maxn][maxn];int n,m;int main(){ scanf("%d",&test); while(test--) { memset(com,0,sizeof(com)); scanf("%s",a); scanf("%s",b); n=strlen(a); m=strlen(b); //初始化 com[m][n]=1; if(b[m-1]=='.'||b[m-1]==a[n-1])com[m-1][n-1]=1; for(int i=m-2;i>=0;i+=2) { if(b[i+1]=='*')com[i][n]=1; else break; } /*if(m-2>=0&&n-1>=0) { if(b[m-1]=='*') { for(int i=n-1;i>=0;i--) { if(a[i]==b[m-1]||b[m-1]=='.')com[m-1][i]=1; else break; } } else { if(n-2>=0) { if(a[n-2]==b[m-2]||b[m-2]=='.')com[m-2][n-2]=1; } } }*/ //初始化结束 for(int i=m-1;i>=0;i--) { if(b[i]=='*')continue; if(b[i+1]=='*') { for(int j=n;j>=0;j--) { if(com[i+2][j]==1) { com[i][j]=1; if(j-1<0)continue; if(b[i]=='.')b[i]=a[j-1]; while(a[j-1]==b[i]) { if(j<=0)break; j--; com[i][j]=1; } } } } else { for(int j=n-1;j>=0;j--) { if(com[i+1][j+1]==1) { if(b[i]==a[j]||b[i]=='.')com[i][j]=1; } } } } /*for(int i=0;i<=m;i++) { for(int j=0;j<=n;j++) { cout<<com[i][j]<<" "; } cout<<endl; }*/ if(com[0][0]==1)printf("yes\n"); else printf("no\n"); }}
后记:
后来看了题解的状态,是从正面开始匹配的,但是按照状态数来说,感觉这个应该还能比他的快一点常数的。
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- 网页H5获取当前坐标,完整demo
- RingerMode 设置和勿扰模式关系
- Jquery面试题
- 用 Kotlin 开启我们的 Activity
- Precision,Recall,F1score,Accuracy的理解
- HDU
- 复习题
- 【转载两篇关于android按键事件传递的文章,流程非常完整】Android按键事件传递流程(一)
- HTML5地理定位
- 一步一步学习androidNDK编程(hello world)
- 智能小车十七《路由器挂载摄像头》
- JAVA 对 海康SDK二次开发
- volatile
- 使用python爬取聚币,云币币种