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;
    }
  • 相关阅读:
    Boost之使用篇(1)
    Lucene 3.0.0细节初窥(1)深入探索Lucene的consumer与processor
    整理一点关于Lucene的学习资料, 方便自己与别人查看
    使用Lucene 3.0.0的结构遍历TokenStream的内容.
    [原创]如何写一个完善的c++异常处理类
    Lucene 3.0.0 的TokenStream与Analyzer
    Lucene 3.0.0 之样例解析(4)IndexFiles.java
    贝叶斯、概率分布与机器学习
    Lucene用c++重写的详细安排
    Lucene 3.0.0的细节初窥(2)研究在索引过程中的缓存
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6816757.html
Copyright © 2011-2022 走看看