zoukankan      html  css  js  c++  java
  • 【POJ

    Cheapest Palindrome

    直接翻译了

    Descriptions

    给定一个字符串S,字符串S的长度为M(M≤2000),字符串S所含有的字符的种类的数量为N(N≤26),然后给定这N种字符Add与Delete的代价,求将S变为回文串的最小代价和。

    Input

    第一行:两个由空格分隔的整数 N 和 M

    第二行:这一行给出了恰好 M 个字符,表示初始状态下的ID字符串

    接下来的 N 行:每一行给出了由空格分隔的三部分。首先是一个字符,保证出现在了输入的字符串中。接下来是两个整数,表示你增添这个字符的代价,然后是删除这个字符的代价

    Output

    你只需要输出一行,且只输出一个整数。表示你将给定字符串变成回文串所需的最小代价。

    Sample Input

    3 4
    abcb
    a 1000 1100
    b 350 700
    c 200 800

    Sample Output

    900

    题目链接

    https://vjudge.net/problem/POJ-3280

    首先要先知道删除一个字母和添加一个字母没有区别,那么这个字母的价值就是value[c]=min(Add,Delete)

    用dp[i][j]表示字符串中第i个字符到第j个字符为回文时,所花费的最小代价。dp[i][j]可以由dp[i+1][j]或者dp[i][j-1]转移而来。例:bcb可以由bc或cb转移而来

    如果第i个字符和第j个字符相同,那么不需要添加其余的操作和代价,dp[i][j] = dp[i+1][j-1]。

    如果第i个字符和第j个字符不同,那么dp[i][j]=dp[i+1][j]删除第i个字符,或者再最右侧添加第i个字符;也可以由dp[i][j-1]删除第j个字符,或者再最左侧添加第j个字符。

    总之要选择第i个字符或第j个字符中删除或者添加代价最小的一种操作进行。

    AC代码

    #include <iostream>
    #include <cstdio>
    #include <fstream>
    #include <algorithm>
    #include <cmath>
    #include <deque>
    #include <vector>
    #include <queue>
    #include <string>
    #include <cstring>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
    #define Mod 1000000007
    #define eps 1e-6
    #define ll long long
    #define INF 0x3f3f3f3f
    #define MEM(x,y) memset(x,y,sizeof(x))
    #define Maxn 2005
    using namespace std;
    int N,M;
    string s;
    int dp[Maxn][Maxn];
    int value[Maxn];//字母的价值
    int main()
    {
        cin>>N>>M;
        cin>>s;
        for(int i=0; i<N; i++)
        {
            char c;
            int x,y;
            cin>>c>>x>>y;
            value[c]=min(x,y);//获取最小价值
        }
        MEM(dp,0);
        for(int j=1; j<M; j++)
        {
            for(int i=j-1; i>=0; i--)
            {
                if(s[i]==s[j])//相等
                    dp[i][j]=dp[i+1][j-1];
                else//不等
                    dp[i][j]=min(dp[i][j-1]+value[s[j]],dp[i+1][j]+value[s[i]]);
            }
        }
        cout<<dp[0][M-1]<<endl;
        return 0;
    }
     
  • 相关阅读:
    如何用C++操作无线网卡开启共享热点WiFi?
    delphi中的copy函数和pos函数
    C#使用WinAPI 修改电源设置,临时禁止笔记本合上盖子时睡眠(使用PowerGetActiveScheme等函数,以及C#对WINAPI的调用)
    发布Qt Widgets桌面应用程序的方法(自定义进程步骤,用QT Creator直接生成)
    认识TDD
    基于Bootstrap的Asp.net Mvc 分页
    Chrome控制台 JS调试
    英语学习
    JavaScript中的作用域和声明提前
    LeetCode: Distinct Subsequences
  • 原文地址:https://www.cnblogs.com/sky-stars/p/11340216.html
Copyright © 2011-2022 走看看