zoukankan      html  css  js  c++  java
  • codeforces159D

    题意:给你一个字符串,问你其中不重叠的回文字串对有多少

    解题思路:这题用到两种方法,不过其实是一个很巧妙的二重dp

    1)暴力求解以i开头,j结尾的是否为回文,如果是,ans += sum[i-1](ans 为答案, sum[i]为在  1 - i内回文串的个数--需要dp求解)

    这里非常耗时,时间大约为  n^3 ,  跑出来为 830ms

    解题代码:

     1 // File Name: 159d.cpp
     2 // Author: darkdream
     3 // Created Time: 2014年07月30日 星期三 16时37分50秒
     4 
     5 #include<vector>
     6 #include<list>
     7 #include<map>
     8 #include<set>
     9 #include<deque>
    10 #include<stack>
    11 #include<bitset>
    12 #include<algorithm>
    13 #include<functional>
    14 #include<numeric>
    15 #include<utility>
    16 #include<sstream>
    17 #include<iostream>
    18 #include<iomanip>
    19 #include<cstdio>
    20 #include<cmath>
    21 #include<cstdlib>
    22 #include<cstring>
    23 #include<ctime>
    24 
    25 using namespace std;
    26 #define LL long long 
    27 char str[2005];
    28 LL sum[2004];
    29 int is(int a,int b)
    30 {
    31      int k = (a+b)/2;
    32      for(int i = a ;i <= k ;i ++ )
    33      {
    34          if(str[i] != str[b-i+a])
    35              return 0 ;
    36      }
    37      return 1;
    38 }
    39 int main(){
    40     scanf("%s",&str[1]);
    41     LL ans = 0 ; 
    42     int len =  strlen(&str[1]);
    43     sum[0] = 0 ;
    44     for(int i = 1 ;i <=len ;i ++)
    45     {
    46          for(int j = 1;j <= i ;j ++)
    47          {
    48             if(is(j,i))
    49             {
    50                ans += sum[j-1];
    51                sum[i] ++ ;
    52             }
    53          }
    54          sum[i] += sum[i-1];
    55     }
    56     printf("%I64d
    ",ans);
    57     return 0;
    58 }
    View Code

    2) 这里在前面一种解法上又多了一次dp,因为我们知道了所有情况的以 i 结尾的回文串以后就可以快速求出所有以 i+1 结尾的回文串,所以这里再加一个dp

    跑出来时间为  30ms  效率提高了 近30倍

    解题代码:

     1 // File Name: 159d.cpp
     2 // Author: darkdream
     3 // Created Time: 2014年07月30日 星期三 16时37分50秒
     4 
     5 #include<vector>
     6 #include<list>
     7 #include<map>
     8 #include<set>
     9 #include<deque>
    10 #include<stack>
    11 #include<bitset>
    12 #include<algorithm>
    13 #include<functional>
    14 #include<numeric>
    15 #include<utility>
    16 #include<sstream>
    17 #include<iostream>
    18 #include<iomanip>
    19 #include<cstdio>
    20 #include<cmath>
    21 #include<cstdlib>
    22 #include<cstring>
    23 #include<ctime>
    24 
    25 using namespace std;
    26 #define LL long long 
    27 char str[2005];
    28 LL sum[2004];
    29 LL tans[2004];
    30 int dp[2000][2000];
    31 int main(){
    32     scanf("%s",&str[1]);
    33     LL ans = 0 ; 
    34     int len =  strlen(&str[1]);
    35     memset(tans,0,sizeof(tans));
    36     for(int i = 1;i <= len ;i ++)
    37         dp[i][0] = 0; 
    38     sum[0] = 0 ;
    39     dp[1][1] = 1; 
    40     tans[1] = 1;
    41     sum[1] = 1; 
    42     for(int i = 2 ;i <=len ;i ++)
    43     {
    44          dp[i][1] = 1; 
    45          tans[i] = 1; 
    46          ans += sum[i-1];
    47          for(int j = 0;j <= tans[i-1];j ++)
    48          {
    49               if(str[i-dp[i-1][j]-1] == str[i])
    50               {
    51                  ans += sum[i-dp[i-1][j]-2];
    52                  tans[i] ++ ;
    53                  dp[i][tans[i]] = dp[i-1][j] + 2;
    54               }
    55          }
    56          sum[i] = sum[i-1] + tans[i];
    57     }
    58 //    printf("%I64d
    ",tans[2]);
    59     printf("%I64d
    ",ans);
    60     return 0;
    61 }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    ASP.NET之电子商务系统开发1(数据列表)
    ASP.NET之电子商务系统开发2(购物车功能)
    MFC之列表控件
    自己动手写操作系统(二)一个最小的“操作系统”
    自己动手写操作系统(一)环境准备
    windows常用快捷键
    MFC之下拉框
    链表反转&交换链表结点
    TinyHttp前置知识
    单链表基本操作总结
  • 原文地址:https://www.cnblogs.com/zyue/p/3878582.html
Copyright © 2011-2022 走看看