您的位置:首页 > 其它

uva 10453 回文串dp uva 10739 uva 11151最长回文串 poj 3280

2015-04-04 17:35 330 查看
uva 10453

题意:

给一个字符串,可以在任意位置插入任意字符,使其变成回文串。

求最小插入的字符数,打印结果。

解析:

记忆化搜索和递归都可以。

打印的时候递归。

详细思路代码。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>

#define LL long long

using namespace std;
const int maxn = 1e3 + 10;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = 4 * atan(1.0);
const double ee = exp(1.0);

char str[maxn];
int dp[maxn][maxn];
int len;

//dp
void DP()
{
memset(dp, 0, sizeof(dp));
for (int d = 2; d <= len; d++)
{
for (int l = 0; l + d - 1 <= len; l++)
{
int r = l + d - 1;
int& ans = dp[l][r] = inf;
if (str[l] == str[r])
{
ans = dp[l + 1][r - 1];
}
ans = min(ans, min(dp[l + 1][r], dp[l][r - 1]) + 1);
}
}
}

int dfs(int i, int j)
{
int& res = dp[i][j];
if (j <= i)
return res = 0;
if (res != inf)
return res;
if (str[i] == str[j])
{
res = dfs(i + 1, j - 1);
}
res = min(res, min(dfs(i + 1, j), dfs(i, j - 1)) + 1);
return res;
}

void output(int i, int j)
{
if (i > j)
return;
if (i == j)
{
printf("%c", str[i]);
return;
}
if (str[i] == str[j])
{
printf("%c", str[i]);
output(i + 1, j - 1);
printf("%c", str[i]);
}
else if (dp[i][j] == dp[i + 1][j] + 1)
{
printf("%c", str[i]);
output(i + 1, j);
printf("%c", str[i]);
}
else
{
printf("%c", str[j]);
output(i, j - 1);
printf("%c", str[j]);
}
}

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
while (scanf("%s", str) != EOF)
{
len = strlen(str);
//        DP();

memset(dp, inf, sizeof(dp));
dfs(0, len - 1);

printf("%d ", dp[0][len - 1]);
output(0, len - 1);
printf("\n");
}
return 0;
}


uva 10739

题意:

给一个字符串,可以添加、删除、替换字母,问the minimum number of characters needed to turn the given string into a palindrome.

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>

#define LL long long

using namespace std;
const int maxn = 1e3 + 10;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = 4 * atan(1.0);
const double ee = exp(1.0);

char s[maxn];
int dp[maxn][maxn];
bool vis[maxn][maxn];

int dfs(int i, int j)
{
if (i > j)
return 0;
if (vis[i][j])
return dp[i][j];
vis[i][j] = true;
if (s[i] == s[j])
return dp[i][j] = dfs(i + 1, j - 1);
if (s[i] != s[j])
{
return dp[i][j] = min(dfs(i + 1, j), min(dfs(i, j - 1), dfs(i + 1, j - 1))) + 1;//删除添加 与 替换
}
}

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
int n;
scanf("%d", &n);
getchar();
for (int t = 1; t <= n; t++)
{
scanf("%s", s);
printf("Case %d: ", t);
int len = strlen(s);
memset(vis, false, sizeof(vis));
memset(dp, 0, sizeof(dp));
int ans = dfs(0, len - 1);
printf("%d\n", ans);
}
return 0;
}


uva 11151 最长回文串

题意:

求一个最长回文串。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>

#define LL long long

using namespace std;
const int maxn = 1000 + 10;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = 4 * atan(1.0);
const double ee = exp(1.0);

int dp[maxn][maxn];
char str[maxn];
char rev[maxn];

int DP(int i, int j)
{
int& res = dp[i][j];
if (i > j)
return 0;
if (i == j)
return 1;
if (res)
return res;
if (str[i] == str[j])
{
res = DP(i + 1, j - 1) + 2;
}
else
{
res = max(DP(i + 1, j), DP(i, j - 1));
}
return res;
}

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
int ncase;
scanf("%d", &ncase);
getchar();
while (ncase--)
{
memset(dp, 0, sizeof(dp));
gets(str);
int len = strlen(str);
//        ///1.LCS 0.085s
//        for (int i = len - 1; i >= 0; i--)
//        {
//            int t = len - i - 1;
//            rev[t] = str[i];
//        }
//        for (int i = 1; i <= len; i++)
//        {
//            for (int j = 1; j <= len; j++)
//            {
//                if (str[i - 1] == rev[j - 1])
//                {
//                    dp[i][j] = dp[i - 1][j - 1] + 1;
//                }
//                else
//                {
//                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
//                }
//            }
//        }
//        printf("%d\n", dp[len][len]);
///2.dp 0.102s
int ans = DP(0, len - 1);
printf("%d\n", ans);
}
return 0;
}


poj 3280:

题意:

给一个字符串,然后可以添加删除字符,把当前这个串变成回文串。

添加和删除都有一定的代价,求把它变成回文串以后的最小代价。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1

using namespace std;
const int maxn = 30;
const int maxm = 2001;
const int inf = 0x3f3f3f3f;
const double eps = 1e-9;
const double pi = acos(-1.0);
const double ee = exp(1.0);

int dp[maxm][maxm];
char str[maxm];
int a[30];

int dfs(int i, int j)
{
int& res = dp[i][j];
if (j <= i)
return res = 0;
if (res != inf)
return res;
if (str[i] == str[j])
{
res = dfs(i + 1, j - 1);
}
res = min(res, min(dfs(i + 1, j) + a[str[i] - 'a'], dfs(i, j - 1) + a[str[j] - 'a']));
return res;
}

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif // LOCAL
int n, m;
while (~scanf("%d%d", &n, &m))
{
scanf("%s", str);
getchar();
for (int i = 0; i < n; i++)
{
char c;
int o, p;
scanf("%c %d %d", &c, &o, &p);
getchar();
a[c - 'a'] = min(o, p);
}
memset(dp, inf, sizeof(dp));
dfs(0, m - 1);
printf("%d\n", dp[0][m - 1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: