hdu4757 最长回文子序列(区间DP)

http://acm.hdu.edu.cn/showproblem.php?pid=4745

Problem Description

Long long ago, there lived two rabbits Tom and Jerry in the forest. On a sunny afternoon, they planned to play a game with some stones. There were n stones on the ground and they were arranged as a clockwise ring. That is to say, the first stone was adjacent
to the second stone and the n-th stone, and the second stone is adjacent to the first stone and the third stone, and so on. The weight of the i-th stone is ai.

The rabbits jumped from one stone to another. Tom always jumped clockwise, and Jerry always jumped anticlockwise.

At the beginning, the rabbits both choose a stone and stand on it. Then at each turn, Tom should choose a stone which have not been stepped by itself and then jumped to it, and Jerry should do the same thing as Tom, but the jumping direction is anti-clockwise.

For some unknown reason, at any time , the weight of the two stones on which the two rabbits stood should be equal. Besides, any rabbit couldn‘t jump over a stone which have been stepped by itself. In other words, if the Tom had stood on the second stone, it
cannot jump from the first stone to the third stone or from the n-the stone to the 4-th stone.

Please note that during the whole process, it was OK for the two rabbits to stand on a same stone at the same time.

Now they want to find out the maximum turns they can play if they follow the optimal strategy.

Input

The input contains at most 20 test cases.

For each test cases, the first line contains a integer n denoting the number of stones.

The next line contains n integers separated by space, and the i-th integer ai denotes the weight of the i-th stone.(1 <= n <= 1000, 1 <= ai <= 1000)

The input ends with n = 0.

Output

For each test case, print a integer denoting the maximum turns.

Sample Input

1
1
4
1 1 2 1
6
2 1 1 2 1 3
0

Sample Output

1
4
5

Hint

For the second case, the path of the Tom is 1, 2, 3, 4, and the path of Jerry is 1, 4, 3, 2.
For the third case, the path of Tom is 1,2,3,4,5 and the path of Jerry is 4,3,2,1,5.
/**
hdu 4745   最长回文子序列  (区间DP)
题目大意:在一个长度为n的环形序列上的任取两个点,一个向左走一个向右走,求他们走了多少步后二人可以再同一个点相遇(题目数据保证他们会在一个点相遇)
解题思路:看了题解我才明白,其实就是求这个环形序列的最长回文子序列,然后考虑两个起点的值相同时的情况就好了
          1、起点相同 maxx=max(maxx,dp[i][i+n-1]);
          2、地点不同  maxx=max(maxx,dp[i][i+n-2]+1);
*/
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
using namespace std;
int dp[2005][2005],a[2005],n;
int main()
{
    while(~scanf("%d",&n))
    {
        if(n==0) break;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            a[i+n]=a[i];
        }
        n*=2;
        memset(dp,0,sizeof(dp));
        for(int i=0;i<=n;i++)
            dp[i][i]=1;
        for(int i=n-1;i>0;i--)
        {
            for(int j=i+1;j<=n;j++)
            {
                dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
                if(a[i]==a[j])
                {
                    dp[i][j]=max(dp[i][j],dp[i+1][j-1]+2);
                }
            }
        }
        /**
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                printf("%d ",dp[i][j]);
            }
            printf("\n");
        }*/
        int maxx=-1;
        n/=2;
        for(int i=1;i<=n;i++)
        {
            maxx=max(maxx,dp[i][i+n-1]);
        }
        ///如果二者各自起始点石头重量相同
        for(int i=1;i<=n;i++)
        {
            maxx=max(maxx,dp[i][i+n-2]+1);
        }
        printf("%d\n",maxx);
    }
    return 0;
}
时间: 2024-11-10 15:26:40

hdu4757 最长回文子序列(区间DP)的相关文章

最长回文子序列 区间dp

J - 买票回家啦 Time Limit:1000MS    Memory Limit:65535KB    64bit IO Format: SubmitStatusPracticeNBUT 1586 Description 集训要结束了,同学们就准备回家了.好舍不得回家阿.(那就再待一个月嘛,就这么愉快地决定了.)超哥要回家了,可是他没有挤进12306官网, 可怜的他就随便找了个能代购车票的网站.结果,当他付钱时傻眼了,这个网站竟然要验证码.验证码嘛就照着样子输入就好了呀,哦不,这个网站管理

最长回文子序列

题目:给你一个字符串,求它的最长回文子序列,比如"bbbab" 最长回文子序列是"bbbb" 所以返回4,,"abab"最长子序列是"aba"或者"bab" 所以返回3 思路:和之前做的几道dp不同,,,也是我不够变通,,打dp表的时候总习惯左上到右下的顺序,但是这个顺序却固化了我的思维,忽略了对于题解本身含义的理解....... 这个题从下到上开始打表,最重要的是它的含义,,,知道dp[i][j]意味着什

soj 4421 最长回文子序列

题意: 给你一个字符串,求该字符串的最长回文子序列长度. 解法: 以前做过连续最长回文子串的长度就是通过构造奇数偶数长度的来做,而本题是不连续. 注意到回文字符串的特点是从左边向右边看和从右边向左边看是一样的效果,那么就可以把目标字符串s导致后产生一个t,子串中如果t和s相同那么这个子串就是回文子串,那么就转化为这两个子串求LCS(longest common subsequent)的问题了. 我的代码: #include <set> #include <map> #include

[最长回文子序列Manacher]4.11终于出线了啊!

Manacher用来求最长回文子序列 1.读入字符串,在每个字符前后加一个没有在原字符串中出现的字符,这样不论是奇数或者偶数个都变成了奇数个 例如: M A N A C H E R # M # A # N # A # C # H # E # R # 2.在开头和末尾再添加一个没有在原字符串中出现的字符,这样就不用讨论越界了 例如: # M # A # N # A # C # H # E # R # $# M # A # N # A # C # H # E # R # \0 3.然后从第一位开始计

算法导论_动态规划_最长回文子序列

一.问题的描述 回文序列(Palindromic sequence, Palindrome)是指正向遍历和反向遍历完全相同的序列,例如字符串"AAAAA"显然是一个回文序列,又如字符串"[email protected]"也是一个回文序列.现在,我们要在一个(字符)序列中找出最长回文子序列的长度.例如字符序列"BBABCBCAB",最长回文子序列是"BACBCAB"(可能不唯一),它的长度是7:子序列"BBBBB&q

回文串区间dp

UVa 10739 String to Palindrome(经典回文串区间DP) 题意: 给定一个字符串,可以对其进行删除,插入,替换操作. 问最少经过几次操作,可以使这个字符串变成回文字符串. 思路: 看得别人的 题解,最优化问题,用较为直接的方法处理时发现情况很复杂,很多时候就要考虑动态规划了.先从整体出发,由大到小,看往少一个两个元素的情况进行最优递归,如何得到结果. (这里区间DP即是不断向两侧扩大规模) (1)如果最外层两个字符相同,s[0]==s[n],那么这两个字符外侧肯定不用考

最长回文子序列(不连续)以及最长回文子串(连续)

整理了一下关于回文子序列和回文子串的程序. 其中(1)和(2)是采用动态规划的思想写出的回文子序列的程序,这种子序列就是在原始的串中可以不连续,比如对于那种要求删除几个字符来得到最长的回文字符串的题就是这种情况. 比如caberbaf.  最长的子序列是5 abeba 或者abrba.而子串最长只有1 (3)(4)(5)都是最长子串的求法.(3)是暴力求解,(4)是改进的暴力求解.(5)采用的是动态规划的方法. 1 #include <iostream> 2 #include <stri

UVa 10617 Again Palindrome(回文串区间DP)

UVa 10617 Again Palindrome(经典回文串区间DP) 题意: 给定一个字符串s,对s进行删除操作,使得剩下的子串是回文字符串,问最多有多少种这种子串. 思路: 涉及到回文字符串,首先要想到的肯定是区间DP,如何写出状态转移方程? 直接从题意切入:dp[i, j]表示区间[i, j]最多有多少个这样的子串. 1. s[i] == s[j] 去掉s[i],则一个子问题就是dp[i+1, j]; 去掉s[j],另一个子问题就是dp[i, j-1]; 显然这两个子问题是会有重叠的,

HDU 4745 Two Rabbits(最长回文子序列)

http://acm.hdu.edu.cn/showproblem.php?pid=4745 题意: 有一个环,现在有两只兔子各从一个点开始起跳,一个沿顺时针,另一个沿逆时针,只能在一圈之内跳,并且每次所在的点的大小必须相同,问最多能经过 几个点. 思路:环状的话可以先倍增改成链. 这道题目的话就是求最长回文子串,它的求法是这样的: 设字符串为str,长度为n,p[i][j]表示第i到第j个字符间的子序列的个数(i<=j),则: 状态初始条件:dp[i][i]=1 (i=0:n-1) 状态转移方