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

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值