HDU4745 Two Rabbits(区间dp)

13 篇文章 0 订阅
13 篇文章 0 订阅

wsfw 卡在最后的答案统计了,看了别人的博客,觉得很有道理。
先破环成链,答案有两种情况:
1.在一段区间(最长为n)中的回文子序列:12321。两人站在l,r的位置开始行动
2.对于一个长度为n-1的序列来说,str[l-1]==str[r+1],所以有一种情况是两人站在l-1,r+1的位置开始行动。(说白了,l-1,r+1是同一个点,这种情况就是起点相同的情况。)

#include <bits/stdc++.h>

using namespace std;
//-----pre_def----
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define fir(i, a, b) for (int i = (a); i <= (b); i++)
#define rif(i, a, b) for (int i = (a); i >= (b); i--)
#define endl '\n'
#define init_h memset(h, -1, sizeof h), idx = 0;
#define lowbit(x) x &(-x)

//---------------
const int N = 2e3 + 10;
int n, d[N];
int f[N][N];
void init() {}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    int StartTime = clock();
#endif
    while (scanf("%d", &n), n)
    {
        fir(i, 1, n)
        {
            scanf("%d", &d[i]), d[i + n] = d[i];
        }
        n <<= 1;
        memset(f, 0, sizeof f);
        fir(i, 1, n) f[i][i] = 1;
        int ans = 0;
        fir(len, 2, n)
        {
            for (int l = 1; l + len - 1 <= n; l++)
            {
                int r = l + len - 1;
                //f[l][r]
                if (d[l] == d[r])
                {
                    f[l][r] = max(f[l][r], f[l + 1][r - 1] + 2);
                }
                else
                {
                    f[l][r] = max({f[l][r], f[l + 1][r], f[l][r - 1]});
                }
            }
        }
        fir(i, 1, n / 2)
        {
            ans = max({ans, f[i][i + n / 2 - 1], f[i][i + n / 2 - 2] + 1});
        }
        printf("%d\n", ans);
    }
#ifndef ONLINE_JUDGE
    printf("Run_Time = %d ms\n", clock() - StartTime);
#endif
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值