• POJ 3280:Cheapest Palindrome 区间DP好题


    Cheapest Palindrome

    题目链接:

    http://poj.org/problem?id=3280

    题意:

    给出一个只由小写字母组成的串,可以添加或删除一些字母(添加和删除都需要花费且花费不同),求将这个串改变成一个回文串的最小花费。

    题解:

    设dp[i][j]是将区间[i,j]改变成回文串的最小花费,则两种情况

            ①显而易见,当s[i]==s[j]时,dp[i][j]=dp[i+1][j-1]

            ②当s[i]!=s[j]时,dp[i][j]有四种可能的取值,区间 [i,j-1] 删除s[i]、在s[j-1]的右侧添加s[i]、区间 [i+1,j] 删除s[j]、在s[i+1]的左侧添加s[j],则此时dp[i][j]=min(dp[i][j-1]+del[i],dp[i][j-1]+add[i],dp[i+1][j]+del[j],dp[i+1][j]+add[j]);

    代码

    #include<stdio.h>
    #include<string.h>
    const int N=2001;
    int dp[N][N],cost1[26],cost2[26];
    char s[N],a[2];
    int mmin(int x,int y)
    {
      return x<y?x:y;
    }
    void solve()
    {
      int n,m,b,c;
      memset(dp,0,sizeof(dp));
      while(~scanf("%d%d",&n,&m))
      {
        scanf("%s",s+1);
        for(int i=1;i<=n;++i)
        {
          scanf("%s%d%d",a,&b,&c);
          cost1[a[0]-'a']=b;
          cost2[a[0]-'a']=c;
        }
        for(int len=1;len<m;++len)
        {
          for(int i=1;i+len<=m;++i)
          {
            int j=i+len;
            if(s[i]==s[j])dp[i][j]=dp[i+1][j-1];
            else
            {
              b=dp[i+1][j]+mmin(cost1[s[i]-'a'],cost2[s[i]-'a']);
              c=dp[i][j-1]+mmin(cost1[s[j]-'a'],cost2[s[j]-'a']);
              dp[i][j]=mmin(b,c);
            }
          }
        }
        printf("%d ",dp[1][m]);
      }
    }
    int main()
    {
      solve();
      return 0;
    }

     
  • 相关阅读:
    Unique Binary Search Trees——LeetCode
    Binary Tree Inorder Traversal ——LeetCode
    Maximum Product Subarray——LeetCode
    Remove Linked List Elements——LeetCode
    Maximum Subarray——LeetCode
    Validate Binary Search Tree——LeetCode
    Swap Nodes in Pairs——LeetCode
    Find Minimum in Rotated Sorted Array——LeetCode
    Linked List Cycle——LeetCode
    VR AR MR
  • 原文地址:https://www.cnblogs.com/kiuhghcsc/p/5748360.html
Copyright © 2020-2023  润新知