题目概述
一序列有N个数,给出序列,问最少可划分为几个不上升子序列
时限
1000ms/2000ms
输入
每行第一个正整数N,其后N个正整数,为序列中的数
限制
1<=序列中的数<=30000
输出
每行一个数,最少划分数
样例输入
8 389 207 155 300 299 170 158 65
4 1 2 1 2
样例输出
2
2
讨论
dp,是的,这是dp,不过确切说,这是dilworth定理,最少的不升子序列划分数等于其最长上升子序列长度,而求最长子序列的平方级算法已经很熟练了
题解状态
15MS,1732K,596 B,C++
题解代码
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 100003
#define memset0(a) memset(a,0,sizeof(a))
int nums[MAXN], dp[MAXN];//存放原始数据 dp辅助数组
int fun(int N)
{
for (int p = 0; p < N; p++) {
scanf("%d", &nums[p]);//input
dp[p] = 1;//没法在下面的步骤初始化 单独处理
for (int i = p; i >= 0; i--)
if (nums[p] > nums[i])
dp[p] = max(dp[p], dp[i] + 1);
}
return *max_element(dp, dp + N);
}
int main(void)
{
//freopen("vs_cin.txt", "r", stdin);
//freopen("vs_cout.txt", "w", stdout);
int N;
while (~scanf("%d", &N)) {//input
printf("%d\n", fun(N));//output
}
}
EOF