335B - Palindrome

题目:

  给出一个字符串(均有小写字母组成),如果有长度为100的回文子串,输出该子串。否则输出最长的回文子串。

分析:

  虽然输入串的长度比较长,但是如果存在单个字母100或以上的话,直接输出即可。

  利用抽屉原理发现,如果不存在上面所说的情况,长度不会超过26*99

  dp[l][r]表示l到r的回文子串的长度,dp转移方式比较明显,记录一下得到最优值时的位置。

  输出方案时,如果dp[1][len]>=100的话,显然可以输出长度100的子串,否则直接输出该长度。

  具体实现用到了栈、队列保存信息,可以看代码。

#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull; #define debug puts("here")
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
#define pb push_back
#define RD(n) scanf("%d",&n)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
#define All(vec) vec.begin(),vec.end()
#define MP make_pair
#define PII pair<int,int>
#define PQ priority_queue
#define cmax(x,y) x = max(x,y)
#define cmin(x,y) x = min(x,y)
#define Clear(x) memset(x,0,sizeof(x))
/* #pragma comment(linker, "/STACK:1024000000,1024000000") int size = 256 << 20; // 256MB
char *p = (char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p) ); */ char IN;
bool NEG;
inline void Int(int &x){
NEG = 0;
while(!isdigit(IN=getchar()))
if(IN=='-')NEG = 1;
x = IN-'0';
while(isdigit(IN=getchar()))
x = x*10+IN-'0';
if(NEG)x = -x;
}
inline void LL(ll &x){
NEG = 0;
while(!isdigit(IN=getchar()))
if(IN=='-')NEG = 1;
x = IN-'0';
while(isdigit(IN=getchar()))
x = x*10+IN-'0';
if(NEG)x = -x;
} /******** program ********************/ const int MAXN = 3005; int cnt[MAXN];
int dp[MAXN][MAXN];
int px[MAXN][MAXN],py[MAXN][MAXN];
int n;
string s,a;
stack<char> b; inline bool check(){
rep(i,26)
if(cnt[i]>=100){
rep(j,100)
putchar( char(i+'a') );
puts("");
return true;
}
return false;
} int dfs(int l,int r){
if(l==r)return dp[l][r] = 1;
if(l>r) return dp[l][r] = 0;
if(~dp[l][r])return dp[l][r]; dp[l][r] = 0;
if(s[l]==s[r]){
px[l][r] = l+1;
py[l][r] = r-1;
dp[l][r] = dfs(l+1,r-1)+2;
}
int t = dfs(l+1,r);
if(t>dp[l][r]){
dp[l][r] = t;
px[l][r] = l+1;
py[l][r] = r;
} t = dfs(l,r-1);
if(t>dp[l][r]){
dp[l][r] = t;
px[l][r] = l;
py[l][r] = r-1;
}
return dp[l][r];
} void path(int l,int r,int res){ // 区间l,r输出长度res的回文子串
int x = px[l][r] , y = py[l][r];
if(l==x&&y==r){
if(res){ // 如果还有
a.pb(s[x]);
res --;
}
return;
}
if(dp[l][r]==2+dp[x][y]){
if(res){ // 如果还可以输出
a.pb(s[l]);
b.push(s[r]);
res -= 2;
}
}
path(x,y,res);
} inline void print(){ // 输出方案
foreach(i,a)
putchar(a[i]);
while(!b.empty()){
putchar( b.top() );
b.pop();
}
puts("");
} int main(){ #ifndef ONLINE_JUDGE
freopen("sum.in","r",stdin);
//freopen("sum.out","w",stdout);
#endif while(getline(cin,s)){
Clear(cnt);
foreach(i,s)
cnt[ s[i]-'a' ] ++;
if(check())continue;
n = s.size();
rep(i,n)
rep(j,n)
px[i][j] = i , py[i][j] = j; memset(dp,-1,sizeof(dp));
int len = dfs(0,s.size()-1); a.clear();
path( 0,s.size()-1,min(100,len) );
print();
} return 0;
}

  

CF 335B - Palindrome 区间DP的更多相关文章

  1. POJ 1159 Palindrome(区间DP/最长公共子序列+滚动数组)

    Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 56150   Accepted: 19398 Desc ...

  2. POJ 3280 Cheapest Palindrome (区间DP) 经典

    <题目链接> 题目大意: 一个由小写字母组成的字符串,给出字符的种类,以及字符串的长度,再给出添加每个字符和删除每个字符的代价,问你要使这个字符串变成回文串的最小代价. 解题分析: 一道区 ...

  3. POJ 3280 Cheapest Palindrome ( 区间DP && 经典模型 )

    题意 : 给出一个由 n 中字母组成的长度为 m 的串,给出 n 种字母添加和删除花费的代价,求让给出的串变成回文串的代价. 分析 :  原始模型 ==> 题意和本题差不多,有添和删但是并无代价 ...

  4. CF 335B. Palindrome(DP)

    题目链接 挺好玩的一个题,1Y... #include <cstdio> #include <cstring> #include <iostream> using ...

  5. Codeforces335B - Palindrome(区间DP)

    题目大意 给定一个长度不超过5*10^4的只包含小写字母的字符串,要求你求它的回文子序列,如果存在长度为100的回文子序列,那么只要输出长度为一百的回文子序列即可,否则输出它的最长回文子序列 题解 这 ...

  6. POJ1159 - Palindrome(区间DP)

    题目大意 给定一个字符串S,问最少插入多少个字符可以使字符串S变为回文串 题解 用dp[i][j]表示把字符串s[i-j]变为回文串需要插入的最小字符数 如果s[i]==s[j]那么dp[i][j]= ...

  7. POJ3280 - Cheapest Palindrome(区间DP)

    题目大意 给定一个字符串,要求你通过插入和删除操作把它变为回文串,对于每个字符的插入和删除都有一个花费,问你把字符串变为回文串最少需要多少花费 题解 看懂题立马YY了个方程,敲完就交了,然后就A了,爽 ...

  8. poj 1159 Palindrome(区间dp)

    题目链接:http://poj.org/problem?id=1159 思路分析:对该问题的最优子结构与最长回文子序列相同.根据最长回文子序列的状态方程稍加改变就可以得到该问题动态方程. 假设字符串为 ...

  9. POJ 3280 - Cheapest Palindrome - [区间DP]

    题目链接:http://poj.org/problem?id=3280 Time Limit: 2000MS Memory Limit: 65536K Description Keeping trac ...

随机推荐

  1. 【转】google推出的SwipeRefreshLayout下拉刷新用法

    SwipeRefreshLayout是Google在support v4 19.1版本的library更新的一个下拉刷新组件,实现刷新效果更方便. 使用如下: 1.先下载android-support ...

  2. struts2对一些属性的使用和对session封装对象类型采用jstl技术的遍历(配图解)

    在struts2中如何实现像jsp中request,session,appliaction的使用.其实有两种方法.下面通过一个案列来说明两个方法的使用. 先写一个test.java类 packagec ...

  3. STM32的TAMPER-RTC管脚作为Tamper使用 - 防拆机

    当 TAMPER引脚上的信号从 0变成1或者从 1变成 0(取决于备份控制寄存器BKP_CR的 TPAL位),会产生一个侵入检测事件.侵入检测事件将所有数据备份寄存器内容清除.  然而为了避免丢失侵入 ...

  4. 六、Linux/UNIX操作命令积累【kill、netstat、df、du】

    在使用Linux/UNIX下,常常会使用文本界面去设置系统或操作系统,作者本人在工作的过程也在不断接触这方面的命令,所以为此特酝酿.准备.開始了本文的编写. 本文主要记录自己平时遇到的一些Linux/ ...

  5. [ACM] hdu 1181 变形课

    变形课 Problem Description 呃......变形课上Harry碰到了一点小麻烦,由于他并不像Hermione那样可以记住全部的咒语而任意的将一个棒球变成刺猬什么的,可是他发现了变形咒 ...

  6. ORCALE用户授权与创建同义词

    创建同义词: DROP public synonym marketmonitor_day; DROP public synonym marketmonitor_month; DROP public s ...

  7. Codeforces Good Bye 2015 A. New Year and Days 水题

    A. New Year and Days 题目连接: http://www.codeforces.com/contest/611/problem/A Description Today is Wedn ...

  8. Maven实战之Quick Start

    Introduction Maven是一个异常强大的构建工具,能够帮我们自动化构建过程,从清理.编译.测试到生成报告,再到打包和部署.通过Maven,我们只需要输入简单的命令(如mvn clean i ...

  9. IdHttpServer实现webservice

    IdHttpServer实现webservice   朋友有个项目,通信协议使用HTTP,数据序列使用BIN(二进制).他不知道要选用何种技术方案. REST webservice是http+json ...

  10. MySQL 调优基础:Linux内存管理 Linux文件系统 Linux 磁盘IO Linux网络

    http://www.cnblogs.com/digdeep/category/739915.html