zoukankan      html  css  js  c++  java
  • POJ 3280 Cheapest Palindrome

    记忆化搜索,$dp$。

    $dp[L][R]$表示将区间$[L,R]$修改为一个回文串需要的最小代价。转移很容易写,区间$dp$或者记忆化搜索都可以。

    区间$dp$:

    #include <cstdio>
    #include <cmath>
    #include <set>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    char s[2010],op[5];
    int dp[2010][2010];
    int c[30][2];
    int m,n;
    
    int main()
    {
        while(~scanf("%d%d",&m,&n))
        {
            scanf("%s",s);
            for(int i=0;i<m;i++)
            {
                scanf("%s",op);
                scanf("%d%d",&c[op[0]-'a'][0],&c[op[0]-'a'][1]);
            }
    
            int len=strlen(s);
            
            for(int L=0;L<len;L++)
            {
                for(int R=L;R<len;R++)
                {
                    dp[L][R]=0x7FFFFFFF;
                }
            }
    
            for(int x = 1;x<=len;x++)
            {
                for(int L=0;L<len;L++)
                {
                    if(x==1)
                    {
                        dp[L][L]=0;
                        continue;
                    }
    
                    int R = L+x-1;
                    if(R>=len) continue;
    
                    if(x==2&&s[L]==s[R])
                    {
                        dp[L][R]=0;
                        continue;
                    }
    
                    if(s[L]==s[R]) dp[L][R] = min(dp[L][R],dp[L+1][R-1]);
                    
                    dp[L][R] = min(dp[L][R], dp[L+1][R]+c[s[L]-'a'][0]);
                    dp[L][R] = min(dp[L][R], dp[L+1][R]+c[s[L]-'a'][1]);
                    dp[L][R] = min(dp[L][R], dp[L][R-1]+c[s[R]-'a'][0]);
                    dp[L][R] = min(dp[L][R], dp[L][R-1]+c[s[R]-'a'][1]);
    
                }
            }
    
            printf("%d
    ",dp[0][n-1]);
    
        }
        return 0;
    }

    记忆化搜索:

    #include <cstdio>
    #include <cmath>
    #include <set>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    char s[2010],op[5];
    int dp[2010][2010];
    int c[30][2];
    int m,n,len;
    
    int dfs(int L,int R)
    {
        if(dp[L][R]!=0x7FFFFFFF) return dp[L][R];
    
        if(R-L==0) dp[L][R]=0;
        else if(R-L==1&&s[L]==s[R]) dp[L][R]=0;
        else 
        {
            int mn = 0x7FFFFFFF;
            if(s[L]==s[R]) mn = min(mn,dfs(L+1,R-1));
            mn = min(mn , dfs(L+1,R)+c[s[L]-'a'][0]);
            mn = min(mn , dfs(L+1,R)+c[s[L]-'a'][1]);
            mn = min(mn , dfs(L,R-1)+c[s[R]-'a'][0]);
            mn = min(mn , dfs(L,R-1)+c[s[R]-'a'][1]);
            dp[L][R] = mn;
        }
    
        return dp[L][R];
    }
    int main()
    {
        while(~scanf("%d%d",&m,&n))
        {
            scanf("%s",s);
            for(int i=0;i<m;i++)
            {
                scanf("%s",op);
                scanf("%d%d",&c[op[0]-'a'][0],&c[op[0]-'a'][1]);
            }
    
            len=strlen(s);
            
            for(int L=0;L<len;L++)
            {
                for(int R=L;R<len;R++)
                {
                    dp[L][R]=0x7FFFFFFF;
                }
            }
    
            printf("%d
    ",dfs(0,n-1));
        }
        return 0;
    }
  • 相关阅读:
    用户模板和用户场景
    移动端疫情展示
    数据爬取
    全国疫情统计可视化地图-第二、三阶段
    学习进度条-第三周
    学习进度条-第二周
    软件工程第二周开课博客
    返回一个整数数组中最大子数组的和
    JavaWeb选课系统(2)
    JavaWeb选课系统
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6816757.html
Copyright © 2011-2022 走看看