HDU4745 Two Rabbits

本文介绍了一种求解最长回文子序列问题的有效算法,通过倍增原序列并在新序列中寻找最长轴对称子环的方法来解决该问题。算法使用动态规划技术,能够高效地找出所有长度为n及n-1的区间内的最长回文子序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

把模型抽象出来,其实就是在一个环中找一个最长的子环,并且这个子环是轴对称的。

从对称轴上一点出发,向两个方向运动可以正好满足题意,并且可以证明如果抽选择的子环不是对称的话,其一定不是最长的。

倍长原序列,在新序列中求所有区间的最长回文子序列长度。

答案就等于所有长度为n的区间中最长回文的长度 和 所有长度为n-1的区间中最长回文的长度+1(在轴上的两点可不同) 中最大的那个。


#pragma comment(linker,"/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
typedef long long ll;

const int maxn = 2010;
int n, n2, ans;
int a[maxn];
int dp[maxn][maxn];

int main()
{
    while (scanf("%d", &n) == 1 && n)
    {
        for (int i=1;i<=n;i++) scanf("%d", &a[i]);
        for (int i=1;i<=n;i++) a[i+n] = a[i];
        memset(dp, 0, sizeof(dp));
        n2 = n+n;
        for (int i=1;i<=n2;i++) dp[i][i] = 1;
        for (int l=2;l<=n;l++)
            for (int i=1;i+l-1<=n2;i++)
            {
                int j = i+l-1;
                dp[i][j] = max(max(dp[i][j], dp[i+1][j-1] + (a[i] == a[j] ? 2 : 0)), max(dp[i+1][j], dp[i][j-1]));
            }
        ans = 0;
        for (int i=1;i<=n;i++) ans = max(ans, dp[i][i+n-1]);
        for (int i=1;i<=n;i++) ans = max(ans, dp[i][i+n-2]+1);
        printf("%d\n", ans);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值