[HDU 4512] 吉哥系列故事——完美队形I 最长上升公共子序列

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

题意:中文题,给你一个 队列,要你在不改变队列顺序的情况下选几个人出来组成一个对称的先上升后下降的队列,问最多选多少人。

思路:将队列倒过来和原队列求最长上升公共子序列,dp[i][k] 表示序列a中[1, i]和b序列中[1, k]选出的最长的以b[k]结尾的上升公共子序列。
这里写图片描述

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

int n;
int arg[210];
int dp[210][210];

int main()
{
    int Test;
    cin>>Test;
    while(Test--){
        cin>>n;
        for(int i = 1; i <= n; i++){
            cin>>arg[i];
        }
        int maxn = 1;
        memset(dp, 0, sizeof(dp));
        for(int i = 1; i <= n; i++) 
        {
            int ans = 0;
            for(int k = n; k > i; k--) 
            {
                dp[i][k] = dp[i-1][k];  //a[i] != b[i]
                if(arg[i] > arg[k] && ans < dp[i-1][k]) //当前循环求得是以a[i]结尾的公共子序列
                    ans = dp[i-1][k]; //保存结尾比a[i]小的最长子序列
                if(arg[i] == arg[k]){  //转移
                    dp[i][k] = ans + 1;
                }
                if((dp[i][k]<<1) > maxn){
                    maxn = dp[i][k]<<1; //对称所以乘二
                }
                for(int l = i+1; l < k; l++) //中间有没有比a[i]大
                {
                    if(arg[l] > arg[k] && (dp[i][k] << 1 | 1) > maxn){
                        maxn = (dp[i][k]<< 1 | 1); //乘 2 加 1 
                    }
                }
            }
        }
        cout<<maxn<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

achonor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值