您的位置:首页 > 大数据 > 人工智能

2016 Multi-University Training Contest 2 1012 La Vie en rose

2016-07-22 15:01 501 查看
题目链接:点击打开链接

题目大意:给你两个字符串a、b,b串中每个字母都可以和相邻的字母交换但只能交换一次,问a串中有多少位置可以和b串匹配。

解题思路:比赛的时候队友是暴力过的,后来看了官方题解打算试一下dp,对于dp[i][j][k](k=0,1,2)表示a字符串匹配到第i位,b字符串匹配到第j位,k=0表示这一位和前一位交换,k=1表示这一位不做任何处理,k=2表示这一位和后一位交换,那么就有一下状态转移方程:

dp[i][j][0]=dp[i-1][j-1][2]&&(a[i]==b[j-1]);

dp[i][j][1]=(dp[i-1][j-1][0]||dp[i-1][j-1][1])&&(a[i]==b[j])

dp[i][j][2]=(dp[i-1][j-1][0]||dp[i-1][j-1][1])&&(a[i]==b[j+1])

代码:

#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<ctime>
#include "cstdio"
#include "string"
#include "string.h"
#include "map"
using namespace std;
int dp[5000][3];
char str1[100001], str2[5001];
int ans[1000001];
int main()
{
int T, m, n;
scanf("%d", &T);
while (T--)
{
memset(ans, 0, sizeof(ans));
memset(dp, 0, sizeof(dp));
scanf("%d %d %s %s", &n, &m, str1, str2);
if (m == 1)
{
for (int i = 0;i < n;i++)
{
if (str1[i] == str2[0])
printf("1");
else
printf("0");
}
puts("");
continue;
}
for (int i = 0;i < n;i++)
{
int now = i+1;
dp[0][1] = (str1[i] == str2[0]);
dp[0][2] = (str1[i] == str2[1]);
//cout << dp[0][1] << " " << dp[0][2] << endl;
if (!(dp[0][1] || dp[0][2]))
continue;
bool flag = true;
for (int j = 1;j < m;j++)
{
if (now == n)
{
flag = false;
break;
}
dp[j][0] = dp[j - 1][2] && (str1[now] == str2[j - 1]);
dp[j][1] = (dp[j - 1][0] || dp[j - 1][1]) && (str1[now] == str2[j]);
if (j != m - 1)
dp[j][2] = (dp[j - 1][0] || dp[j - 1][1]) && (str1[now] == str2[j + 1]);
if (dp[j][0] || dp[j][1] || dp[j][2])
now++;
else
{
flag = false;
break;
}
}
if (flag)
ans[i] = 1;
}
for (int i = 0;i < n;i++)
printf("%d", ans[i]);
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息