九度OJ 1262:Sequence Construction puzzles(I)_构造全递增序列 (DP)
- 题目描述:
-
给定一个整数序列,请问如何去掉最少的元素使得原序列变成一个全递增的序列。
- 输入:
-
输入的第一行包括一个整数N(1<=N<=10000)。
接下来的一行是N个满足题目描述条件的整数。
- 输出:
-
可能有多组测试数据,对于每组数据,
输出去掉最少的元素后的全递增序列。
- 样例输入:
-
8 186 186 150 200 160 130 197 220
- 样例输出:
-
150 160 197 220
- 提示:
-
如果有多个结果序列满足条件,输出相对位置靠前的那个序列。
思路:
此题并不是求最长递增序列这么简单,这句话才是本题难点所在:
如果有多个结果序列满足条件,输出相对位置靠前的那个序列。
本人第一遍一直在想各种方式保存状态,达到目的,却一直各种错误。
后来放弃了在原有的代码上修改,重写了一遍,AC了。
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define N 10000 typedef struct node { int id; int mNum; struct node *next; } Post; int n; int a[N+1]; int mLen; Post *p[N+1]; Post *insert(Post *t, int id) { Post *h = (Post *)malloc(sizeof(Post)); h->id = id; h->next = t; h->mNum = a[id]; if (!t) mLen ++; else if (t->mNum > h->mNum) h->mNum = t->mNum; return h; } int main(void) { int i, j; while (scanf("%d", &n) != EOF) { for(i=0; i<n; i++) scanf("%d", &a[i]); memset(p, 0, sizeof(p)); mLen = 0; for (i=n-1; i>=0; i--) { for (j=mLen; j>0; j--) { Post *t = p[j]; if (t && t->mNum > a[i]) { while (t) { if (a[t->id] > a[i]) break; } p[j+1] = insert(p[j+1], i); break; } } if (j == 0) p[1] = insert(p[1], i); } int step = mLen; Post *t = p[step]; int id = t->id; printf("%d", a[id]); step --; while (step) { t = p[step]; while (t->id <= id) t = t->next; id = t->id; printf(" %d", a[id]); step --; } printf("\n"); } return 0; } /************************************************************** Problem: 1262 User: liangrx06 Language: C Result: Accepted Time:20 ms Memory:1824 kb ****************************************************************/
编程算法爱好者。