UVALive 6697 - Homework Evaluation(dp,字符串匹配得分)
来源:互联网 发布:apache ab测试百度 编辑:程序博客网 时间:2024/05/07 00:59
题目链接:
UVALive 6697 - Homework Evaluation
题意:
给出两个字符串,用第二个去匹配第一个字符串,第二个字符串中的字母可以看成:新插入的,有丢失的,正确匹配的,不正确的。
- 正确的+8分
- 错误的-5分
- 插入或删除一个字母-3分
- 连续插入或删除额外扣除-4分
例如:
应用上面的规则可以得到的分数是:
现在给出两个字符串(第一个长度不大于100,第二个长度不大于50),问最优得分是多少?
分析:
我们可以发现第二个字符串的每个字母要么和第一个字符串的某个字母匹配,要么看成是插在第一个字符串的某个字母前面。
- 用
dp[0][i][j] 表示第二个字符串的第i 个字母和第一个字符串的第j 个字母匹配时,前i 个字母的得分 - 用
dp[1][i][j] 表示第二个字符串的第i 个字母插在第一个字符串的第j 个字母前面时,前i 个字母的得分
考虑状态转移方程。设字符串的下标都是从1开始,第一个字符串为
- 考虑初始化。
memset(dp, 0, sizeof(dp));if( i > 1) dp[0][i][1] = -3 * (i - 1) - 4;if(ss[i] == s[1]) dp[0][i][1] += 8;else dp[0][i][1] -= 5;dp[1][i][1] = -i * 3 - 4;dp[0][i][0] = dp[1][i][0] = -inf;
- 当第二个字符串的第
i 和第一个字符串的第j 个匹配时,遍历第一个字符串的前j 个字母,考虑第二个字符串的第i−1 个字母的匹配位置k ,先初始化dp[0][i][j]=−inf
对于dp[0][i][j] ,也就是恰好第i个和第j个匹配 。- 如果
k<j−1 ,如果第i−1 个也和第k 个恰好匹配(从dp[0][i−1][k] 转移),那么就相当于在第i 个和第i−1 个之间连续删除了(j−k−1)个字母 ,所以如果第dp[0][i][j]=max(dp[0][i][j],dp[0][i−1][k]−3∗(j−k−1)−4); i−1 个插入在第k 个之前(从dp[1][i−1][k] 转移),那么就相当于在第i 个和第i−1 个之间连续删除了j−k个 ,所以有:dp[0][i][j]=max(dp[0][i][j],dp[1][i−1][k]−3∗(j−k)−4); - 如果
k=j−1 ,同样的道理可得:dp[0][i][j]=max(dp[0][i][j],dp[0][i−1][k]);//既不插入也不删除 dp[0][i][j]=max(dp[0][i][j],dp[1][i−1][k]−3∗(j−k)−4);//j−k=1,正好也相当于插入1个
对于dp[1][i][j] ,也就是恰好第i个插在第j个 之前。同样的道理考虑状态转移。
对于第i−1 个和第j 个匹配或者插入在第j 个之前的情况也是需要考虑的。
- 如果
dp[0][i][j] = max(dp[0][i][j], dp[1][i - 1][j]);if(ss[i] == s[j]) dp[0][i][j] += 8;else dp[0][i][j] -= 5;if(i > 1) dp[1][i][j] = max(dp[1][i][j], dp[1][i - 1][j] - 3);
最后扫一下第二个字符串的最后一个字母在第一个字符串中的匹配位置,结果取最右。别忘了第二字符串的最后一个字母可以看成插入在第一个字符串的最后一个字母后面的情况。
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <climits>#include <cmath>#include <ctime>#include <cassert>#define IOS ios_base::sync_with_stdio(0); cin.tie(0);using namespace std;typedef long long ll;const int MAX_N = 110;int T;char s[MAX_N], ss[MAX_N];int dp[2][MAX_N][MAX_N];int main(){ scanf("%d", &T); while(T--) { scanf("%s%s", s + 1, ss + 1); int len1 = strlen(s + 1) + 1, len2 = strlen(ss + 1) + 1; if(len1 == len2 && len1 == 2) { if(s[1] == ss[1]) printf("8\n"); else printf("-5\n"); continue; } memset(dp, 0, sizeof(dp)); for(int i = 1; i < len2; ++i) { if( i > 1) dp[0][i][1] = -3 * (i - 1) - 4; if(ss[i] == s[1]) dp[0][i][1] += 8; else dp[0][i][1] -= 5; dp[1][i][1] = -i * 3 - 4; dp[0][i][0] = dp[1][i][0] = INT_MIN / 2; for(int j = 2; j < len1 + 1; ++j) { dp[0][i][j] = dp[1][i][j] = INT_MIN; for(int k = 0; k < j; ++k) { if(k < j - 1) dp[0][i][j] = max(dp[0][i][j], dp[0][i - 1][k] - 3 * (j - k - 1) - 4); else dp[0][i][j] = max(dp[0][i][j], dp[0][i - 1][k]); dp[0][i][j] = max(dp[0][i][j], dp[1][i - 1][k] - 3 * (j - k) - 4); if(k < j - 1) dp[1][i][j] = max(dp[1][i][j], dp[0][i - 1][k] - 3 * (j - k - 1) - 11); else dp[1][i][j] = max(dp[1][i][j], dp[0][i - 1][k] - 7); dp[1][i][j] = max(dp[1][i][j], dp[1][i - 1][k] - 3 * (j - k) - 11); } dp[0][i][j] = max(dp[0][i][j], dp[1][i - 1][j]); if(ss[i] == s[j]) dp[0][i][j] += 8; else dp[0][i][j] -= 5; if(i > 1) dp[1][i][j] = max(dp[1][i][j], dp[1][i - 1][j] - 3); } } int ans = INT_MIN, n = len2 - 1; for(int i = 1; i < len1; ++i) { ans = max(ans, dp[0][n][i]); ans = max(ans, dp[1][n][i]); } ans = max(ans, dp[1][n][len1]); printf("%d\n", ans); } return 0;}
0 0
- UVALive 6697 - Homework Evaluation(dp,字符串匹配得分)
- UVAlive 6697 - Homework Evaluation(DP)
- uvalive 6697 - Homework Evaluation - dp
- POJ 1080 Human Gene Functions(字符串匹配得分,dp)
- hdoj1074_Doing Homework(dp)
- UVaLive 6697 (DP)
- Doing Homework (状压dp)
- Doing Homework (状态dp)
- UVALIVE 3516(DP)
- Bzoj 4922(字符串匹配新高度+DP)
- DP-回文字符串匹配
- UVALive 6430 Points(dp)
- UVALive 6848Fishing(dp)
- UVALive 7365 Composition (DP)
- UVALive 3305 Tour(DP)
- hdu1074 Doing Homework(状态压缩dp)
- hdu1074 Doing Homework (状态压缩dp)
- HDU 1074 Doing Homework(状态DP)
- JavaScript indexOf() 方法
- Top 67 Log Management Tools
- hadoop集群配置启动及编程
- 关于iOS中的手势识别
- CDMA手机鉴权的过程说明
- UVALive 6697 - Homework Evaluation(dp,字符串匹配得分)
- 专题四 · 1008
- POJ 2559 Largest Rectangle in a Histogram
- iOS --- 如何在Swift项目中使用runtime?
- 为什么不可使用虚假的IMEI或MEID号码?
- ATS 的三种解决方法
- 欢迎使用CSDN-markdown编辑器
- 关注用户体验
- Python Web 6 —— Python操作MongoDB数据库