题目地址:http://poj.org/problem?id=3898

题目意思:

给你一个模式串,再给你一个原串,要你去匹配

模式串里面的?可对应任意一个字符

*号可对应0个或多个字符

其中a=1,b=2....要你找出在原串中能匹配出的最小值

如果不能就输出-1

这是一道DP的题,其实和LCS很像,但是打比赛的时候我竟然在想各种匹配算法啊,给跪了

尼玛DP简直就是一条不归路啊

解题思路:

用dp[i][j]来表示模式串的第i个和原串的第j个匹配时的值

不能匹配就是INF

那么有几个转移的

对于?,dp[i][j] = dp[i-1][j-1]+cost[j]

对于字符,如果s1[i]==s2[j],dp[i][j] = dp[i-1][j-1]+cost[j]

对于*,因为*可以对应0个或多个

则dp[i][j] = dp[i][j]=min{dp[i-1][k]+sum(cost[k]~cost[j])}

对于第三种还有优化

因为sum(cost[k]~cost[j]) = sum[j]-sum[k],所以我们用一个cur维护dp[i-1][k]-sum[k]的最小值

然后加sum[j]就OK了,这个就直接降了一个维度下来

实在是很妙啊,DP虽然有时候很难,但是想通了确实有美妙的地方在里面

下面上代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5.  
  6. const int maxn = 1010;
  7.  
  8. char s1[maxn];
  9. char s2[maxn*10];
  10.  
  11. int dp[maxn][maxn*10];
  12. int sum[maxn*10];
  13. const int inf = 0x3f3f3f3f;
  14.  
  15. int main()
  16. {
  17. while(~scanf("%s%s",&s1[1],&s2[1]))
  18. {
  19. int len1 = strlen(&s1[1]);
  20. int len2 = strlen(&s2[1]);
  21.  
  22. sum[0] = 0;
  23.  
  24. for(int i=1;i<=len2;i++)
  25. sum[i] = sum[i-1]+(s2[i]-'a'+1);
  26. for(int i=0;i<=len1;i++)
  27. for(int j=0;j<=len2;j++)
  28. dp[i][j] = inf;
  29.  
  30. //对于可以做头的原串,初始化
  31. for(int i=0;i<=len2;i++)
  32. {
  33. if(i>0 && (s1[1]=='?' || s1[1]==s2[i]))
  34. dp[1][i] = sum[i]-sum[i-1];
  35. else if(s1[1]=='*')
  36. dp[1][i] = 0;
  37. }
  38.  
  39. bool flag = true;
  40. for(int i=2;i<=len1;i++)
  41. {
  42. flag = false;
  43. if(s1[i]=='*')
  44. {
  45. int cur = inf;
  46. if(dp[i-1][0] == 0)
  47. {
  48. dp[i][0] == 0;
  49. cur = 0;
  50. flag = true;
  51. }
  52. for(int j=1;j<=len2;j++)
  53. {
  54. if(dp[i-1][j]-sum[j]<cur)
  55. cur=dp[i-1][j] - sum[j];
  56. if(cur+sum[j] < dp[i][j])
  57. dp[i][j] = cur+sum[j],flag = true;
  58. }
  59.  
  60. }
  61. else
  62. {
  63. for(int j=1;j<=len2;j++)
  64. {
  65. if(dp[i-1][j-1]==inf)
  66. continue;
  67. if(s1[i]=='?' || s2[j]==s1[i])
  68. {
  69. dp[i][j] = min(dp[i][j],dp[i-1][j-1]+s2[j]-'a'+1);
  70. flag = true;
  71. }
  72. }
  73. }
  74. if(!flag)
  75. break;
  76. }
  77.  
  78. if(!flag)
  79. {
  80. puts("-1");
  81. continue;
  82. }
  83.  
  84. int ans = inf;
  85.  
  86. for(int i=1;i<=len2;i++)
  87. ans = min(ans,dp[len1][i]);
  88. if(ans == -1)
  89. puts("-1");
  90. else
  91. printf("%d\n",ans);
  92.  
  93. }
  94. return 0;
  95. }

Software Industry Revolution----POJ3898----DP的更多相关文章

  1. poj-3898 Software Industry Revolution DP

    题目链接: http://poj.org/problem?id=3898 题目意思: 有两个字符串,模式串和原串.每个字母有一个权值,a为1,b为2,...z为26 模式串中‘ ?’可以被一个字母代替 ...

  2. {POJ}{3988}{Software Industry Revolution}{DP好题}

    题意:给定一个字符串d,要求用另一字符串s去匹配,其中s中的?可以为任何字符,*可以为任意个字符,求最小的匹配权值 思路:这题和CSDN英雄会的“反相互”类似,由于其中某些字符的不确定性,利用动态规划 ...

  3. Codeforces Round #189 (Div. 1) C - Kalila and Dimna in the Logging Industry 斜率优化dp

    C - Kalila and Dimna in the Logging Industry 很容易能得到状态转移方程 dp[ i ] = min( dp[ j ] + b[ j ] * a[ i ] ) ...

  4. CF 319C - Kalila and Dimna in the Logging Industry 斜率优化DP

    题目:伐木工人用电锯伐木,一共需要砍n棵树,每棵树的高度为a[i],每次砍伐只能砍1单位高度,之后需要对电锯进行充电,费用为当前砍掉的树中最大id的b[id]值.a[1] = 1 , b[n] = 0 ...

  5. Poj 1973 Software Company(二分+并行DP)

    题意:软件公司接了两个项目,来自同一个合同,要一起交付.该公司有n个程序猿来做这两个项目A和B,每个项目都被分为m个子项目,给定每个程序猿做一个A中的子项目需要的时间Xi秒,和做B中的子项目所需时间Y ...

  6. UVALive - 2031 Dance Dance Revolution 三维dp

    题目大意:有一个胖子在玩跳舞机.刚開始的位置在(0,0).跳舞机有四个方向键,上左下右分别相应1,2,3,4.如今有下面规则 1.假设从0位置移动到随意四个位置,消耗能量2 2.假设从非0位置跳到相邻 ...

  7. {POJ}{动态规划}{题目列表}

    动态规划与贪心相关: {HDU}{4739}{Zhuge Liang's Mines}{压缩DP} 题意:给定20个点坐标,求最多有多少个不相交(点也不相交)的正方形 思路:背包问题,求出所有的正方形 ...

  8. 微软职位内部推荐-Software Development Engineer

    微软近期Open的职位: Job Title: Software Development Engineer Work Location: Suzhou, China The Office 365 Co ...

  9. 【Software Test】Introduction to Software Testing

    Introduction to Software Testing 文章目录 Going to Learn --. Evolution of The Software Industry Errors, ...

随机推荐

  1. 【软测试】(两)计算机组成原理-cpu

    cpu,中文名称中央处理单元,central processing unit.系统的核心,用于数据的处理,算术以及逻辑运算和控制程序的运行. 组成 运算器 从字面上就能够理解到.运算器主要用来对于逻辑 ...

  2. java中HashSet详解

    HashSet 的实现 对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSe ...

  3. ApacheBench(ab)使用简介

    网站性能压力测试是服务器网站性能调优过程中必不可缺少的一环.只有让服务器处在高压情况下,才能真正体现出软件.硬件等各种设置不当所暴露出的问题. 性能测试工具目前最常见的有以下几种:ab.http_lo ...

  4. 在windows server里,对于同一个账号,禁止或允许多个用户使用该账户,同时登录

    开始 -> 运行 -> gpedit.msc -> 本地计算机 策略 -> 计算机配置 -> 管理模板 -> Windows 组件 -> 远程桌面服务 -&g ...

  5. 如何使用C API来操作UCI

    https://forum.openwrt.org/viewtopic.php?pid=183335#p183335 Compiling UCI as stand alone with an exam ...

  6. 轨道sql谈话 dbms_monitor

    经常会遇到一个会话存在sql性能问题,但找不到哪一个sql导致DB更高的性能问题,这是我们需要在此session通过监测dbms_monitor软件包来实现. 首先确定要监控的会话sid及serial ...

  7. Andy Williams 《Love Story》

    where do i beginto tell a story of how great a love can bethe sweet love story that is older than th ...

  8. error: C1083: 无法打开包括文件:“QDomDocument”“QAxObject”

    包含了头文件但是提示无法打开包括文件,是需要在项目的.pro里面手动加上一个变量 针对QAxObject是 QT       += axcontainer 针对QDomDocument是 QT     ...

  9. Roslyn 编译平台概述

    在Language Feature Status上面看到,其实更新的并不是特别多,为了不会误导看了C# 6.0 功能预览 (一)的园友,现在把官方的更新列表拿了过来,供大家参考 C# 6.0 功能预览 ...

  10. bootstrap弹出框

    要想使用Bootstrap Popover(弹出框)则必须引入其依赖的文件: jquery.js这个必须的(还是要写在其他js前面,bootstrap是依赖jquery的哦) bootstrap-to ...