zoukankan      html  css  js  c++  java
  • BZOJ 1710. [Usaco2007 Open]Cheappal 廉价回文

    传送门

    看一眼感觉不太可做,推推性质

    发现因为回文串去掉左右还是回文的,所以为了构成回文添加一个字符其实等价于删除另一边对应的字符

    那么删除字符的代价就直接和添加字符的代价取最小值

    然后考虑 $dp$,设 $f[l][r]$ 表示当前 $[l,r]$ 的区间内删除若干字符后成为回文串的最小代价,因为回文去掉两边还是回文

    所以如果 $l,r$ 处的字符相等那么可以从 $f[l+1][r-1]$ 转移

    当然对于任何位置都有转移: $f[l][r]=f[l][r-1]+cost[s[r]],f[l][r]=f[l+1][r]+cost[s[l]]$,其中 $cost[s[i]]$ 表示把位置 $i$ 的字符删除的代价

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2007;
    int n,m,cst[233],f[N][N];
    char s[N];
    int main()
    {
        n=read(),m=read();
        scanf("%s",s+1); char ch[7]; int a,b;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",ch),a=read(),b=read();
            cst[ch[0]-'a']=min(a,b);
        }
        memset(f,0x3f,sizeof(f));
        for(int i=1;i<=m;i++)
            for(int j=i+1;j<=m;j++) f[j][i]=0;
        for(int i=m;i;i--)
            for(int j=i;j<=m;j++)
            {
                if(i==j) { f[i][j]=0; continue; }
                f[i][j]=min(f[i][j-1]+cst[s[j]-'a'],f[i+1][j]+cst[s[i]-'a']);
                if(s[i]==s[j]) f[i][j]=min(f[i][j],f[i+1][j-1]);
            }
        printf("%d
    ",f[1][m]);
        return 0;
    }
    View Code
  • 相关阅读:
    数据结构算法
    C++字符串完全指引之二 —— 字符串封装类
    gethostbyname根据主机名获得地址方法
    通过注册表来限定程序的使用时限
    查询图像上的匹配块
    VC++6.0中内存泄漏检测
    qsort 浅析
    shell 中数学计算总结
    最新感悟基础才是王道
    条件表达式中的匹配
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11417369.html
Copyright © 2011-2022 走看看