洛谷1970 花匠(DP)

本文介绍了一种使用动态规划(DP)解决寻找高低循环中最长序列问题的方法。通过定义两个状态f[i]和g[i],分别表示以i为结尾的最长序列在高位和低位的情况,利用树状数组维护最大值,优化后的算法将状态范围扩大,简化了状态转移过程。

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

题意

找一个高低循环的最长XX序列。

题解

DP
设f[i]表示以i为结尾的最长XX序列,其中i在高位。
设g[i]表示以i为结尾的最长XX序列,其中i在低位。
这两个可以相互转移,即f[i]=max_{i>j,a[i]>a[j]}{g[j]}+1,同样g也有一个转移方程。
接下来用树状数组维护一下max就可以得到50分了。

如何优化呢?
更改一下定义:
设f[i]表示前i个数字中的最长XX序列,其中i在高位。
设g[i]表示前i个数字中的最长XX序列,其中i在低位。
这样转移就方便很多了,f[i]=f[i-1]或者f[i]=g[i-1]+1(前提:a[i]>a[i-1]),g同理。

总结

把状态笼统一些的表达出来(即范围更广),那么转移会更加方便。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; 
const int maxn=100010;

int n;
int a[maxn];
int f[maxn],g[maxn]; 

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    f[1]=g[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(a[i]>a[i-1]) f[i]=g[i-1]+1;
        else f[i]=f[i-1];
        if(a[i]<a[i-1]) g[i]=f[i-1]+1;
        else g[i]=g[i-1];
    }
    printf("%d\n",max(f[n],g[n]));
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值