zoukankan      html  css  js  c++  java
  • 求回文串的组合数

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27623#problem/D

    题目大意:给你一串字符串,在满足第一个回文串右边小于第二个回文串左边的情况下,能组成多少个回文串。

    解题思路:个人感觉是一道不错的dp题,先预处理出所有的f[i][j],f[i][j]表示i到j是否是一个回文串。这里比较巧妙的利用到一点dp,如果字符i等于字符j,那么     f[i][j]=f[i+1][j-1]。然后再预处理出前i个字符能组成的回文串数,再求解。

    这题开始没考虑清楚,我是枚举所有分界点,处理两边的字串,出问题了,因为这样会重复处理...

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 typedef long long lld;
     8 const int maxn=2222;
     9 int f[maxn][maxn], sum[maxn];
    10 char s[maxn];
    11 
    12 int main()
    13 {
    14     while(cin >> s)
    15     {
    16         memset(f,0,sizeof(f));
    17         int len=strlen(s);
    18         for(int i=0; i<len; i++) f[i][i]=1;
    19         for(int i=1; i<len; i++)     ///枚举间隔
    20             for(int j=0; j<len; j++)
    21             {
    22                 int k=j+i;
    23                 if(k<len&&s[j]==s[k])
    24                 {
    25                     if(i==1) f[j][k]=1;
    26                     else f[j][k]=f[j+1][k-1];  ///根据中间包夹的字符串推出现在的串是否为回文串,很巧妙
    27                 }
    28             }
    29         memset(sum,0,sizeof(sum));
    30         for(int i=0; i<len; i++)
    31             for(int j=0; j<len; j++)
    32                 if(i+j<len&&f[j][j+i]) sum[j+i]++;
    33         for(int i=1; i<len; i++) sum[i]+=sum[i-1];
    34         lld ans=0;
    35         for(int i=1; i<len; i++)  ///以i为分界点
    36             for(int j=i; j<len; j++)
    37                 if(f[i][j]) ans+=sum[i-1];
    38         cout << ans <<endl;
    39     }
    40     return 0;
    41 }
    View Code
  • 相关阅读:
    元数据的优势
    老婆从今天开始出差
    清单元数据表中的导出类型定义
    Singleton模式
    拖管代码的优势
    元数据
    "软件随想录"阅读笔记
    《敏捷软件开发》学习笔记:敏捷设计原则
    项目管理中的三个"凡是"
    Python基础(1):数据类型
  • 原文地址:https://www.cnblogs.com/kane0526/p/3226558.html
Copyright © 2011-2022 走看看