zoukankan      html  css  js  c++  java
  • qsc54(区间dp)

    题目链接:http://qscoj.cn/problem/54/

    题意:中文题诶~

    思路:区间dp

    我们可以用dp[i][j]存储区间[i, j]最少需要的打印次数,若没有相同的字母,那么需要的打印次数为dp[i+1, j]+1 (尾字符放在外层循环枚举,首字符放在内一层循环枚举,至于原因在后面会说明)。我们再枚举一个k为[i, j]的中间节点,将[i, j]分成两个子串,由子串的最优解状态转移得到当前串的最优解;那么有[i, j]被分解成[i, k], [k+1, j],

    所以有: dp[i][j]=dp[i, k] + dp[k+1][j];若str[k]==str[j],则dp[i, k]==dp[i+1, k] ,所以动态转移方程式为dp[i][j]=min(dp[i][j], dp[i+1][k]+dp[k+1][j]);

    注意这里k>i,所以 i 必须放到内循环,不然用未更新的dp[k+1][j]去更新dp[i][j]自然是不能保证得到正确答案;其实就是枚举每个尾节点的所有情况啦。

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define MAXN 60
     5 using namespace std;
     6 
     7 char str[MAXN];
     8 int dp[MAXN][MAXN];//dp[i][j]存储区间[i,j]至少要打印多少次
     9 
    10 int main(void){
    11     while(~scanf("%s", str)){
    12         memset(dp, 0, sizeof(dp));
    13         int len=strlen(str);
    14         for(int i=0; i<len; i++){//i为尾字符
    15             for(int j=i; j>=0; j--){//j为头字符
    16                 dp[j][i]=dp[j+1][i]+1;//若没有重复的字符,那么[i,j]可以由[i+1,j]+1得到
    17                 for(int k=j+1; k<=i; k++){
    18                     if(str[k]==str[j]){//枚举中间字符,若str[k]==str[j],则dp[i][k]==dp[i+1][k]
    19                         dp[j][i]=min(dp[j][i], dp[j+1][k]+dp[k+1][i]);
    20                     }
    21                 }
    22             }
    23         }
    24         printf("%d
    ", dp[0][len-1]);
    25     }
    26     return 0;
    27 }
    View Code
  • 相关阅读:
    使脱排油烟机能够听懂你的话(超级简单的方法)
    解决手机无法连接【小米AI音箱】播放音乐问题
    相机稳定器使用注意点
    Scrapy基本命令
    Linux环境下的Scala环境搭建
    Linux基本操作
    MySQL常用操作
    PySpark笔记
    Linux环境下配置及启动Hadoop(伪集群)
    idea: unable to import maven project
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6597111.html
Copyright © 2011-2022 走看看