zoukankan      html  css  js  c++  java
  • 区间dp(低价回文)

    【题目大意】

      追踪每头奶牛的去向是一件棘手的任务,为此农夫约翰安装了一套自动系统。他在每头牛身上安装了一个电子身份标签,当奶牛通过扫描器的时候,系统可以读取奶牛的身份信息。目前,每个身份都是由一个字符串组成的,长度为M (1≤M≤2000),所有的字符都取自小写的罗马字母。

    奶牛们都是顽皮的动物,有时她们会在通过扫描器的时候倒着走,这样一个原来身份为abcb的奶牛就可能有两个不同的身份了(abcb和bcba),而如果身份是abcba的话就不会有这个问题了。

    约翰想改变奶牛们的身份,使他们不管怎么走读起来都一样。比如说,abcb可以在最后加个a,变成回文abcba;也可以在前面加上bcb,变成回文bcbabcb;或者去除字母a,保留的bcb也是一条回文。总之,约翰可以在任意位置删除或插入一些字符使原字符串变成回文。

    不巧的是,身份标签是电子做的,每增加或删除一个字母都要付出相应的费用(0≤代价≤10000)。给定一头奶牛的身份标签和增加或删除相关字母的费用,找出把原来字符串变成回文的最小费用。注意空字符串也是回文。

    【输入格式】

      第一行:两个用空格分开的整数:N和M 第二行:一个长度恰好为M的字符串,代表初始的身份标签 第三行到第N+2行:每行为一个用空格分开的三元组:其中包括一个字符和两个整数,分别表示增加或删除这个字符的费用

    【输出格式】
      第一行:只有一个整数,表示改造这个身份标签的最小费用

    【样例】
      样例输入
      3 4
      abcb
      a 1000 1100
      b 350 700
      c 200 800

    【样例输出】
      900

    【大体思路】

       首先,要搞明白的是,插入和删除操作其实是等价的;

      例:

        abcb,我们可以在右面插入a使其成为回文,也可以在左面删去a使其成为回文,效果是一样的;

      故,对于字符k有v[k-'a']=min(insert[k],delete[k]);

      对于最新扩展的区域,我们需要保证首尾字母相等,即a[i]=a[j],那么dp[i][j]就可以由上一状态转移过来,即dp[i][j]=dp[i+1][j-1];

      如果首尾字母不相等,那么我们比较左右两端修改所需要的代价,取代价最小者,即dp[i][j]=min(dp[i+1][j]+v[a[i]-'a'],dp[i][j-1]+v[a[j]-'a']);

    【代码如下】

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int inf=1e8;
    const int maxn=2000;
    int dp[maxn+20][maxn+20];
    int n,m,v[30];
    char a[maxn+20];
    void read(){//读入数据
        scanf("%d%d",&n,&m);
        scanf("%s",&a);
        char ch;
        int v1,v2;
        for(int i=1;i<=n;i++){
            scanf(" %c %d%d",&ch,&v1,&v2);
            v[ch-'a']=min(v1,v2);//求修改每个字母需要的最小花费
        }
        
    }
    int main(){
        read();
        for(int j=1;j<m;j++){
            for(int i=j-1;i>=0;i--){
                dp[i][j]=inf;//因为要求最小值,故赋值为无穷大
                if(a[i]==a[j])//如果两端相等,继承上一状态
                    dp[i][j]=dp[i+1][j-1];
                else
                    dp[i][j]=min(dp[i+1][j]+v[a[i]-'a'],dp[i][j-1]+v[a[j]-'a']);//如果两端不相等,比较选择最优
            }
        }
    
        printf("%d
    ",dp[0][m-1]);
        return 0;
        
    } 
  • 相关阅读:
    beego学习笔记(4):开发文档阅读(1)
    go的匿名组合
    beego学习笔记(3)
    beego学习笔记(2)
    python发送post请求发送json数据时,报415的原因和处理方法。
    Kali Linux的安装
    linux下配置mysql的远程访问
    selenium学习笔记
    Fiddler使用方法简介
    使用webdriver打开本地浏览器--python版
  • 原文地址:https://www.cnblogs.com/soda-ma/p/12890866.html
Copyright © 2011-2022 走看看