HDU2205 又见回文(区间DP)

题意:给定两个字符串(可能为空串),求这两个串交叉组成新串的子串中的回文串的最大长度。

布尔型变量dp[i][j][k][l]表示串a从i到j,b从k到l能否组成新串,初始化为false,则采取区间动态规划。(从1计数)

1 #include<algorithm>

2 #include<cmath>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<iostream>
 7 #include<map>
 8 #include<queue>
 9 #include<string>
10 #include<vector>
11 typedef long long LL;
12 using namespace std;
13 
14 char a[100], b[100];
15 const int N = 1008, INF = 0x3F3F3F3F;
16 bool dp[52][52][52][52];
17 
18 int main(){
19     while(gets(a + 1) && gets(b + 1)){
20         int la = strlen(a + 1);
21         int lb = strlen(b + 1);
22         memset(dp, 0, sizeof(dp));
23 
24         for(int i = 1; i <= la + 1; i++){
25             for (int j = 1; j <= lb + 1; j++){
26                 dp[i][i][j][j - 1] = dp[i][i - 1][j][j] = dp[i][i - 1][j][j - 1] = 1;
27             }
28         }
29 
30         int ans = 0;
31         for(int l1 = 0; l1 <= la; l1++){
32             for(int l2 = 0; l2 <= lb; l2++){
33                 for(int i = 1, j = i + l1 - 1; j <= la; i++, j++){
34                     for(int k = 1, l = k + l2 - 1; l <= lb; k++, l++){
35                         if(!dp[i][j][k][l]){
36                         bool b1 = i <= j && a[i] == a[j] && dp[i + 1][j - 1][k][l];
37                         bool b2 = k <= l && b[k] == b[l] && dp[i][j][k + 1][l - 1];
38                         bool b3 = l > 0 && a[i] == b[l] && dp[i + 1][j][k][l - 1];
39                         bool b4 = j > 0 && b[k] == a[j] && dp[i][j - 1][k + 1][l];
40                         dp[i][j][k][l] = b1 || b2 ||b3 ||b4;
41                         }
42                         if(dp[i][j][k][l]  && l1 + l2 > ans){
43                             ans = l1 + l2;
44                         }
45                     }
46                 }
47             }
48         }
49         printf("%d\n", ans);
50     }
51     return 0;
52 }

时间: 2024-10-02 21:51:40

HDU2205 又见回文(区间DP)的相关文章

台州 OJ 1704 Cheapest Palindrome 回文 区间DP

题目意思:给一个字符串和每个字母删除.插入的代价,求把它变成回文串的最小代价 dp[i][j] 表示 区间 i~j 的子串变成回文串需要的最小代价. 设字符串 ab....cd 如果 a == d,则将其变成回文串的最小代价就是将  b....c 变成回文串 如果 a != d,考虑如下四种情况 在左边插入一个等于 d 的字符变成  dab....cd,则将其变成回文串的代价是将 ab....c 变成回文串的代价,加上插入 d 的代价. 在将左边的 a 删除变成 b....cd,则将其变成回文串

NYOJ781 又见回文数

又见回文数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 冷淡的回文数被水了,各种被水,然后他很生气,然后... 一个数从左边读和从右边读一样,就说这个数是回文数.如121就是一个回文数. 这个简单了点,咱们这样规定:给定一个十进制数,你判断一下在二~十六进制下她是否是回文数,你能征服她吗? 如17用十进制表示它不是回文数,但是用二进制表示(10001),它是一个回文数. 输入 输入包含一些整数.每个数n(0<n<50000)用十进制表示,每个数一行.输入0结束

NYOJ 752 又见回文串

又见回文串 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 回文串"是一个正读和反读都一样的字符串,比如"level"或者"noon"等等就是回文串.今天,PIAOYI又遇见一个关于字符串的题:两人玩一个游戏,给一个字符串,两人轮流删除字符串中的任意一个字符,当某人删除字符后,若该字符串可以经过重新整理后是一个回文串,则他获胜.当两人足够聪明均不出现操作失误的情况,先手是否可以获胜. 输入 多组测试数据,输入一个字符串(所有字

nyoj 781 又见回文数

又见回文数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 冷淡的回文数被水了,各种被水,然后他很生气,然后... 一个数从左边读和从右边读一样,就说这个数是回文数.如121就是一个回文数. 这个简单了点,咱们这样规定:给定一个十进制数,你判断一下在二~十六进制下她是否是回文数,你能征服她吗? 如17用十进制表示它不是回文数,但是用二进制表示(10001),它是一个回文数. 输入 输入包含一些整数.每个数n(0<n<50000)用十进制表示,每个数一行.输入0结束

SCUT 125 :笔芯回文(DP)

https://scut.online/p/125 125. 笔芯回文 题目描述 bxbx有一个长度一个字符串SS,bxbx可以对其进行若干次操作. 每次操作可以删掉一个长度为k(1 \leq k \leq n)k(1≤k≤n)的连续回文子串,bxbx获得a_ka?k??的愉悦值. 一个字符串是回文串当且仅当正读和反读都是一样的.例如"a", "aa", "abcba""a","aa","abcb

hdu 6156 Palindrome Function(回文数位dp)

题目链接:hdu 6156 Palindrome Function 题意: 给你一个L,R,l,r,问你在[L,R]内在[l,r]进制下有多少数是回文数,然后算一算贡献. 题解: 由于答案和该回文数的最高位有关(因为前导0不算). 考虑dp[i][j][k],表示在i进制下,当前考虑到第j位,该数字的起始点在第k位. 然后开一个数组记录一下前面的数字,做一下记忆化搜索就行了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,siz

还是回文(dp)

还是回文 时间限制:2000 ms  |  内存限制:65535 KB 难度:3 描述 判断回文串很简单,把字符串变成回文串也不难.现在我们增加点难度,给出一串字符(全部是小写字母),添加或删除一个字符,都会产生一定的花费.那么,将字符串变成回文串的最小花费是多少呢? 输入 多组数据 第一个有两个数n,m,分别表示字符的种数和字符串的长度 第二行给出一串字符,接下来n行,每行有一个字符(a~z)和两个整数,分别表示添加和删除这个字符的花费 所有数都不超过2000 输出 最小花费 样例输入 3 4

bzoj 1138: [POI2009]Baj 最短回文路 dp优化

1138: [POI2009]Baj 最短回文路 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 161  Solved: 48[Submit][Status] Description N个点用M条有向边连接,每条边标有一个小写字母. 对于一个长度为D的顶点序列,回答每对相邻顶点Si到Si+1的最短回文路径. 如果没有,输出-1. 如果有,输出最短长度以及这个字符串. Input 第一行正整数N和M ( 2 ≤ N ≤ 400 , 1 ≤ M ≤

BZOJ 1138 [POI2009]Baj 最短回文路 DP

题意:链接略 方法: DP 解析: 显然我们可以找回文中点然后宽搜向两边拓展. 不过这样的复杂度的话- 枚举中点再拓展,岂不有点爆炸? 所以我们换个方式来优化. 我们设F[i][j]表示由i到j的最短回文路径长度. 设G[i][j][k]表示从i到j走一条回文路径再走一个小写字母k的最短回文路径长度. 有了这个辅助式子,问题就变得简单多了. 所有的状态最多也就n^2*k个. 直接上宽搜即可. F[i][j]=min{G[z][j][k]+1&&edge[i][z]==k} G[i][j][