您的位置:首页 > 其它

Codeforces Round #358 (Div. 2) D. Alyona and Strings(DP)

2016-07-09 22:03 375 查看
题目链接:点击打开链接

思路:

类似于LCS, 只需用d[i][j][k][p]表示当前到了s1[i]和s2[j], 形成了k个子序列, 当前是否和上一个字符相连形成一个序列的最长序列和。

细节参见代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>
#include <list>
#include <deque>
#include <map>
#include <queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
typedef long double ld;
const double eps = 1e-6;
const double PI = acos(-1);
const int mod = 1000000000 + 7;
const int INF = 0x3f3f3f3f;
// & 0x7FFFFFFF
const int seed = 131;
const ll INF64 = ll(1e18);
const int maxn = 1000 + 10;
int T,n,m, d[maxn][maxn][12][2], vis[maxn][maxn][12][2], kase = 0, k;
inline bool vail(int i, int j) {
if(i < n && j < m) return true;
else return false;
}
char s1[maxn], s2[maxn];
int dp(int i, int j, int s, int p) {
int& ans = d[i][j][s][p];
if(s > k) return -INF;
if(i >= n || j >= m) {
if(s == k) return 0;
else return -INF;
}
if(vis[i][j][s][p] == kase) return ans;
vis[i][j][s][p] = kase;
ans = 0;
if(p) {
if(s1[i] == s2[j]) ans = max(ans, dp(i+1, j+1, s, p) + 1);
if(s1[i] == s2[j]) ans = max(ans, dp(i+1, j+1, s+1, p) + 1);
ans = max(ans, dp(i+1, j+1, s, p^1));

ans = max(ans, dp(i, j+1, s, p^1));
ans = max(ans, dp(i+1, j, s, p^1));
}
else {
if(s1[i] == s2[j]) ans = max(ans, dp(i+1, j+1, s+1, p^1) + 1);
ans = max(ans, dp(i+1, j+1, s, p));
ans = max(ans, dp(i, j+1, s, p));
ans = max(ans, dp(i+1, j, s, p));
}
return ans;
}
int main() {
scanf("%d%d%d",&n,&m,&k);
++kase;
scanf("%s%s", s1, s2);
int ans = dp(0, 0, 0, 0);
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: