zoukankan      html  css  js  c++  java
  • 想(dp)

    给出一个音符序列,求最长子序列,满足其由若干个低-高-中-高-(中-高-中-高……)组成。(n le 1e5)

    好题啊。类比最长不下降子序列的思想,考虑储存最后两位数,推出dp方程(用到了前缀和思想)。

    这道题的启发性在于:

    • 对于(有有f[i][j]=f[i-1][j])类转移的dp,用滚动数组可能会更舒适
    • 状态的定义不一定要统一。例如本题中的(f[i][j][k][0-3]),j和k的含义就根据后面的数字是几来决定。只要状态定义不重不漏,并且转移方程正确就行了。
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int maxn=1e5+5, INF=0x3f3f3f3f, maxm=100;
    int n, a[maxn], m, max3;
    int f0[maxm][maxm], f1[maxm][maxm], f2[maxm][maxm], f3[maxm][maxm];
    void up(int &x, int y){ if (x<y) x=y; }
    
    int main(){
    	scanf("%d", &n); max3=0;
    	for (int i=1; i<=n; i++) scanf("%d",&a[i]), m=max(a[i], m);
    	memset(f0,-INF, sizeof(f0)); memset(f1, -INF, sizeof(f1));
    	memset(f2, -INF, sizeof(f2)); memset(f3,-INF, sizeof(f3)); 
    	for (int i=1; i<=n; i++){
    		int x=a[i];
    		for (int j=x+1; j<=m; j++) up(f0[x][j], max3+1);
    		for (int j=1; j<x; j++) up(f1[j][x], f0[j][x]+1);
    		for (int j=1; j<=m; j++) up(f1[j][x], f1[j-1][x]);
    		for (int j=x+1; j<=m; j++) up(f2[x][j], max(f1[x-1][j], f3[x][j])+1);
    		for (int j=1; j<x; j++) 
    			up(f3[j][x], f2[j][x]+1), up(max3, f3[j][x]);
    	}
    	printf("%d
    ",max3);
    	return 0;
    } 
    
  • 相关阅读:
    Python进程池multiprocessing.Pool的用法
    基于opencv的车牌提取项目
    Srapy 爬取知乎用户信息
    Scrapy框架简介及小项目应用
    豆瓣爬取图书标签
    CSS选择器使用
    关于 urlencode 的使用和 json 模块的介绍
    urllib库使用方法
    猫眼电影的各种爬取方法
    淘宝商品信息爬取
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/9571413.html
Copyright © 2011-2022 走看看