zoukankan      html  css  js  c++  java
  • 动态规划(2)——区间DP(NYOJ1023还是回文)*

    还是回文

    时间限制:2000 ms  |  内存限制:65535 KB
    难度:3
    描述

    判断回文串很简单,把字符串变成回文串也不难。现在我们增加点难度,给出一串字符(全部是小写字母),添加或删除一个字符,都会产生一定的花费。那么,将字符串变成回文串的最小花费是多少呢?

     
    输入
    多组数据
    第一个有两个数n,m,分别表示字符的种数和字符串的长度
    第二行给出一串字符,接下来n行,每行有一个字符(a~z)和两个整数,分别表示添加和删除这个字符的花费
    所有数都不超过2000
    输出
    最小花费
    样例输入
    3 4
    abcb
    a 1000 1100
    b 350 700
    c 200 800
    样例输出
    900

    题目大意:

        1、先给一个m,一个n

        2、再给一个字符串char str[MAX](MAX为一个很大的数),字符串长度为n

        字符串中的字符全为小写字母,m为这个字符串中字符的种类总数。例如m=3,n=4,str="abcb",str的长度为4,由a b c三类字符组成。

        3、接下来是m组数据,每组三个元素。每一组的第一个元素为字符,第二个为整数表示增加该字符的代价,第三个为整数表示删除该字符的代价。

        4、求使得str变为一个回文串的最小操作代价是多少(对str中的字符都是可删可增)。

    解题思路:

    *用别人的代码作为参考,自己想着应该是下面的意思,先琢磨着吧,发现有误的话,再更改。

        1、cost[26]对给出的所有的字符只保留对某个字符操作的最小操作代价,例如:a,1000(增),1100(删);那么cost['a'-'a']=1000;

        2、dp[MAX][MAX](MAX为一个很大的值)对字符串str进行处理,i,j表示dp[i][j]是对str第i位到第j位之间的字符串操作使其变为回文串的最小操作代价值。

            那么对于每个i到j的字符串都会有两种处理方案,(1)对i位置操作的代价+对i+1到j之间的字符串进行操作的最小代价(2)对i到j-1之间的字符串进行操作的最小代价+对ji位置操作的代价,所以就会得到:dp[i][j]=min(dp[i+1][j]+cost[str[i]-'a'],dp[i][j-1]+cost[str[j]-'a']);

           如果,str[i]==str[j],我们可以将i到j之间的串进行两种操作,1把它当做它自身来操作,2把它当做i+1到j-1之间的一个字符串来进行操作,例如:abcca,可以单纯的当做abcca进行上一段的操作,也可以就当做bcc来进行操作。所以,当str[i]==str[j]的时候,dp[i][j]=min(dp[i][j],dp[i+1][j-1]);

        3、输出dp[0][n-1]即可。

    AC代码如下:

        

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    #define MAX 2100
    int cost[26];
    int dp[MAX][MAX];
    char str[MAX];
    int main()
    {
        int n;int m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            scanf("%s",str);
            for(int i=0;i<n;i++)
            {
                char s[2];int a;int b;
                scanf("%s%d%d",s,&a,&b);
                cost[s[0]-'a']=a<b?a:b;
            }
            for(int j=1;j<m;j++)
            {
                for(int i=j-1;i>=0;i--)
                {
                    dp[i][j]=min(dp[i+1][j]+cost[str[i]-'a'],dp[i][j-1]+cost[str[j]-'a']);
                    if(str[i]==str[j])
                       dp[i][j]=min(dp[i+1][j-1],dp[i][j]);
                }
            }
            printf("%d
    ",dp[0][m-1]);
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    mac os programming
    Rejecting Good Engineers?
    Do Undergrads in MIT Struggle to Obtain Good Grades?
    Go to industry?
    LaTex Tricks
    Convert jupyter notebooks to python files
    How to get gradients with respect to the inputs in pytorch
    Uninstall cuda 9.1 and install cuda 8.0
    How to edit codes on the server which runs jupyter notebook using your pc's bwroser
    Leetcode No.94 Binary Tree Inorder Traversal二叉树中序遍历(c++实现)
  • 原文地址:https://www.cnblogs.com/xueniwawa/p/3741145.html
Copyright © 2011-2022 走看看