把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

Cheapest Palindrome POJ - 3280【dp-区间dp 回文】

传送门

来自vjudge的题意


分析

定义状态:dp[i][j] 为把区间i~j变成回文的最小代价


转移:
s[i]==s[j] dp[i][j]=dp[i+1][j-1]
如果 s[i+1]~s[j]是回文串 则对于s[i]可以增加可以删除,dp[i][j]=dp[i+1][j]+min(ac(s[i]),dc(s[i]))
如果 s[i]~s[j-1]是回文串 则对于s[j]可以增加可以删除,dp[i][j]=dp[i][j-1]+min(ac(s[j]),dc(s[j]))

(有同志问为什么dp[i+1][j]可以对应条件 如果 s[i+1]~s[j]是回文串 其实就是对于dp[i+1][j],既然它都表示变成回文的代价了,那这个区间就是回文,如果它已经计算过,就可以直接转移 这是dp呐 不是说要判断它是否回文,利用这样的思路计算代价而已 如果你没有这样的疑问,请略过此处


这几种情况取min
由于dp[i][j]要从dp[i+1][j-1]、dp[i+1][j]、dp[i][j-1]中转移过来,所以i反着枚举,j正着枚举
几种情况取min dp[i][i]要置为0(一个字符本身就是回文)

考虑到对于一个字符增加和删除对结果并没有什么影响,所以只要对这个字符有改动就用增加的删除中的小的代价
那么在存储时可以只存ac和dc中小的那一个


#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAXM 2010
#define INF 0x3f
int n,m;
char s[MAXM];
int c[26];
int dp[MAXM][MAXM];//区间i~j的最小代价
int main()
{
    scanf("%d %d",&n,&m);
    scanf("%s",s);//从0开始!!!
    for(int i=1;i<=n;i++)
    {
        char tmp[5];//有换行符,非常非常非常非常非常坑!!!
        int x,y;
        scanf("%s",tmp);
        scanf("%d %d",&x,&y);
        c[tmp[0]-'a']=min(x,y);
    }
    for(int i=m-1;i>=0;i--)
    {
        dp[i][i]=0;
        for(int j=i+1;j<m;j++)
        {
            dp[i][j]=INF;//之前用memset和fill全局清都WA了,至今未果,还是不要随便全局了,只清要比较的qwq
            if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1];
            dp[i][j]=min(dp[i][j],dp[i+1][j]+c[s[i]-'a']);
            dp[i][j]=min(dp[i][j],dp[i][j-1]+c[s[j]-'a']);
        }
    }
    printf("%d\n",dp[0][m-1]);
    return 0;
}
posted @   Starlight_Glimmer  阅读(8)  评论(0编辑  收藏  举报  
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
浏览器标题切换
浏览器标题切换end
点击右上角即可分享
微信分享提示