zoukankan      html  css  js  c++  java
  • UVA 1626 区间dp、打印路径

    uva

    紫书例题,这个区间dp最容易错的应该是(S)这种匹配情况,如果不是题目中给了提示我就忽略了,只想着左右分割忘记了这种特殊的例子。

    dp[i][j]=MIN{dp[i+1][j-1] | if(match(i,j) , dp[i][k]+dp[k+1][j] | i<=k<=j .}
    注意初始化dp[i][i]=1,表示1个字符最少需要一个才能匹配,dp[i+1][i]=0,因为可能只有两个字符使得i+1>j-1,我们可以认为中间是空字符已经匹配了。

    打印路径利用了递归,很巧妙,lrj的代码确实短小精悍。

    还有就是本题的输入输出要注意,可能出现空串,输入的每一行字符间(包括第一行字符和t之间)都要键入一个空格,输出每两个答案之间输出一个空格。

    为了防止getline()将输入的t读入到s中,我们将t以字符形式读入。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define inf 0x3f3f3f3f
     4 int dp[110][110];
     5 char s[115];
     6 bool match(int i,int j)
     7 {
     8     return (s[i]=='['&&s[j]==']')||(s[i]=='('&&s[j]==')');
     9 }
    10 void print(int l,int r)
    11 {
    12  if(l>r) return;
    13  if(l==r){
    14     if(s[l]=='['||s[r]==']') printf("[]");
    15     else printf("()");
    16     return;
    17  }
    18  if(dp[l][r]==dp[l+1][r-1]&&match(l,r)){
    19     printf("%c",s[l]);
    20     print(l+1,r-1);
    21     printf("%c",s[r]);
    22     return;
    23  }
    24  for(int k=l;k<=r;++k){
    25     if(dp[l][r]==dp[l][k]+dp[k+1][r]){
    26         print(l,k);
    27         print(k+1,r);
    28         return;
    29     }
    30  }
    31 }
    32 int main()
    33 {
    34     int t,n,m=0,i,j,k;
    35     cin.getline(s,105);
    36     t=atoi(s);
    37     while(t--){getchar();m++;
    38     if(m>1) puts("");
    39     cin.getline(s+1,105);
    40         n=strlen(s+1);
    41         memset(dp,inf,sizeof(dp));
    42         for(i=0;i<=n;++i)
    43         {
    44             dp[i][i]=1;
    45             dp[i+1][i]=0;
    46         }
    47         for(int len=2;len<=n;++len)
    48         {
    49             for(i=1,j=len;j<=n;++i,++j)
    50             {
    51                 if(match(i,j)) dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
    52                 for(k=i;k<=j;++k)
    53                 {
    54                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
    55                 }
    56             }
    57         }
    58         //cout<<dp[1][n]<<endl;
    59         print(1,n);puts("");
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    EF的连表查询Lambda表达式和linq语句
    C#.NET里面抽象类,接口,虚方法
    ASP.Net WebAPI的返回值
    IHttpActionResult不识别解决办法
    web api 开发之 filter
    SQL语句大全教程
    ASP.NET Web API 跨域访问(CORS)要注意的地方
    铁乐学python_shelve模块详解
    铁乐学python_day25_序列化模块
    铁乐学python_day24_面向对象进阶1_内置方法
  • 原文地址:https://www.cnblogs.com/zzqc/p/7323863.html
Copyright © 2011-2022 走看看