Codeforces 1144G Two Merged Sequences dp

Two Merged Sequences

感觉是个垃圾题啊, 为什么过的人这么少。。

dp[ i ][ 0 ]表示处理完前 i 个, 第 i 个是递增序列序列里的元素,递减序列的最大值。

dp[ i ][ 1 ]表示处理完前 i 个, 第 i 个是递减序列序列里的元素,递增序列的最小值。

然后随便转移转移顺便记录一下路径就好啦。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;

const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000000007;
const double eps = 1e-6;
const double PI = acos(-1);

int n, a[N], ans[N];
int dp[N][2], path[N][2];

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for(int i = 1; i <= n; i++)
        dp[i][0] = -inf, dp[i][1] = inf;
    dp[1][0] = 1e9 + 1;
    dp[1][1] = -1;
    for(int i = 1; i < n; i++) {
        if(dp[i][0] > -inf) {
            if(a[i + 1] > a[i]) {
                if(dp[i][0] > dp[i + 1][0]) {
                    dp[i + 1][0] = dp[i][0];
                    path[i + 1][0] = 0;
                }
            }
            if(a[i + 1] < dp[i][0]) {
                if(a[i] < dp[i + 1][1]) {
                    dp[i + 1][1] = a[i];
                    path[i + 1][1] = 0;
                }
            }
        }
        if(dp[i][1] < inf) {
            if(a[i + 1] < a[i]) {
                if(dp[i][1] < dp[i + 1][1]) {
                    dp[i + 1][1] = dp[i][1];
                    path[i + 1][1] = 1;
                }
            }
            if(a[i + 1] > dp[i][1]) {
                if(a[i] > dp[i + 1][0]) {
                    dp[i + 1][0] = a[i];
                    path[i + 1][0] = 1;
                }
            }
        }
    }
    if(dp[n][0] > -inf) {
        puts("YES");
        int now = 0;
        for(int i = n; i >= 1; i--) {
            ans[i] = now;
            now = path[i][now];
        }
        for(int i = 1; i <= n; i++) printf("%d ", ans[i]);
        puts("");
    } else if(dp[n][1] < inf) {
        puts("YES");
        int now = 1;
        for(int i = n; i >= 1; i--) {
            ans[i] = now;
            now = path[i][now];
        }
        for(int i = 1; i <= n; i++) printf("%d ", ans[i]);
        puts("");
    } else {
        puts("NO");
    }
    return 0;
}

/*
*/

原文地址:https://www.cnblogs.com/CJLHY/p/10634175.html

时间: 2024-10-08 18:32:47

Codeforces 1144G Two Merged Sequences dp的相关文章

CodeForces 446A DZY Loves Sequences (DP+暴力)

题意:给定一个序列,让你找出一个最长的序列,使得最多改其中的一个数,使其变成严格上升序列. 析:f[i] 表示以 i 结尾的最长上升长度,g[i] 表示以 i 为开始的最长上升长度,这两个很容易就求得,最后枚举中间值即可. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib>

CodeForces 447C DZY Loves Sequences DP

题目:click here 题意:求给定序列更改其中一个元素后的最长连续上升子序列的长度 分析:最长的连续子序列有2种,一种是严格上升(没有更改元素)的长度加1,一种是两段严格上升的加起来.. 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define F first 4 #define S second 5 #define pb push_back 6 #define power(a) ((a)*(a)) 7 #define ENT

Codeforces #550 (Div3) - G.Two Merged Sequences(dp / 贪心)

Problem  Codeforces #550 (Div3) - G.Two Merged Sequences Time Limit: 2000 mSec Problem Description Two integer sequences existed initially, one of them was strictly increasing, and another one — strictly decreasing. Strictly increasing sequence is a

codeforces 446A DZY Loves Sequences

codeforces   446A   DZY Loves Sequences         题目链接:http://codeforces.com/problemset/problem/446/A 题目大意:给出一个定长为n的数列a,问改动当中一个数后.可能出现的最长严格上升子段的长度是多少. 题目分析:先不考虑"改动当中一个数"这个条件,这样问题就简单多了,从前到后遍历计数就可以(定义一个数组inc[]长度同a,初始化全部点为1,遍历假设当前点a[i]>a[i-1]就置inc

【矩阵快速幂 】Codeforces 450B - Jzzhu and Sequences (公式转化)

[题目链接]click here~~ [题目大意] Jzzhu has invented a kind of sequences, they meet the following property: You are given x and y, please calculate fn modulo1000000007(109?+?7). [解题思路] /*A - Jzzhu and Sequences Codeforces 450B - Jzzhu and Sequences ( 矩阵快速幂 )

Codeforces 360C Levko and Strings dp

题目链接:点击打开链接 题意: 给定长度为n的字符串s,常数k 显然s的子串一共有 n(n-1)/2 个 要求找到一个长度为n的字符串t,使得t对应位置的k个子串字典序>s #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<vector> #include<set> using namespace std; #

CodeForces 30C Shooting Gallery 简单dp

题目链接:点击打开链接 给定n个气球 下面n行 x y t val 表示气球出现的坐标(x,y) 出现的时刻t,气球的价值val 枪每秒移动1个单位的距离 问: 射击的最大价值,开始时枪瞄准的位置任意. 思路: dp一下.. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <math.h> #include <set

Codeforces 459E Pashmak and Graph(dp+贪心)

题目链接:Codeforces 459E Pashmak and Graph 题目大意:给定一张有向图,每条边有它的权值,要求选定一条路线,保证所经过的边权值严格递增,输出最长路径. 解题思路:将边按照权值排序,每次将相同权值的边同时加入,维护每个点作为终止点的最大长度即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 3

codeforces 149D - Coloring Brackets (区间dp)

题目大意: 给出一组合法的括号. 括号要么不涂颜色,要么就涂上红色或者绿色. 匹配的括号只能有一个有颜色. 两个相邻的括号不能有相同的颜色. 思路分析: 因为是一个合法的括号序列. 所以每个括号与之匹配的位置是一定的. 那么就可以将这个序列分成两个区间. (L - match[L] )  (match[L]+1, R) 用递归先处理小区间,再转移大区间. 因为条件的限制,所以记录区间的同时,还要记录区间端点的颜色. 然后就是一个递归的过程. #include <cstdio> #include