【DP】划分数列(ybtoj DP-2-1)
生活随笔
收集整理的這篇文章主要介紹了
【DP】划分数列(ybtoj DP-2-1)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
劃分數列
ybtoj DP-2-1
題目大意
給你一個數列,讓你劃分出最少的段數,使每段要么單調不降,要么單調不增
輸入樣例#1
6
1 2 3 2 2 1
輸出樣例#1
2
輸入樣例#2
9
1 2 1 2 1 2 1 2 1
輸出樣例#2
5
輸入樣例#3
7
1 2 3 2 1 999999999 1000000000
輸出樣例#3
3
數據范圍
1?n?100000,ai1\leqslant n \leqslant 100000, a_i1?n?100000,ai?在 intintint范圍內。
解題思路
設fi,1,fi,2f_{i,1},f_{i,2}fi,1?,fi,2?為前i個數劃分,且最后一段為下降/上升的最小劃分段數
如果ai?ai?1a_i\geqslant a_{i-1}ai??ai?1?那么fi,2=fi?1,2f_{i,2}=f_{i-1,2}fi,2?=fi?1,2?
如果ai?ai?1a_i\leqslant a_{i-1}ai??ai?1?那么fi,1=fi?1,1f_{i,1}=f_{i-1,1}fi,1?=fi?1,1?
就是加進最后一段
如果重開一段,那就+1
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 100010 using namespace std; int n, a[N], f[N][3]; int main() {memset(f, 127/3, sizeof(f)); scanf("%d", &n);scanf("%d", &a[1]);f[1][1] = f[1][2] = 1;for (int i = 2; i <= n; ++i){scanf("%d", &a[i]);if (a[i] >= a[i - 1]) f[i][2] = f[i - 1][2];//直接加進去if (a[i] <= a[i - 1]) f[i][1] = f[i - 1][1];f[i][1] = min(f[i][1], min(f[i - 1][1], f[i - 1][2]) + 1);//新開一段f[i][2] = min(f[i][2], min(f[i - 1][1], f[i - 1][2]) + 1);}printf("%d", min(f[n][1], f[n][2]));//求最大值return 0; }總結
以上是生活随笔為你收集整理的【DP】划分数列(ybtoj DP-2-1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【矩阵乘法】沼泽鳄鱼(ssl 2511)
- 下一篇: 【贪心】奶牛晒衣服(ybtoj 贪心-1