ACM 题目 - 最长上升子序列 - WA求助

gqjjqg 2010-06-26 09:53:10
http://acm.nit.net.cn/showproblem.jsp?pid=1557
OJ地址,很多地方也有同样的题目....
题目描述:
一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, ..., aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1<= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1, 3, 5, 8)。

输入:

多组cas , 每组cas 两行:

第一行 输入一个数 n , 表示有n个数

第二行 n个数, 分别代表每个数;

输出

每个cas 一行 输出 该书数列的最长的长度 ;

输入样例:

7

1 7 3 5 9 4 8

输出样例:

4

---------------
O(n^2)貌似我会,O(nlogn)虽然网上有资料,看不太明白意思..

求代码错误指正....总是Wa....
是我的想法错了么?

#include <stdio.h> 
int G_iNumberList[1000000];
int G_iNumberStat[1000000];
int G_iNumberCount;
int main()
{
while (1 == scanf("%d", &G_iNumberCount))
{
int i, j;
for (i = 0; i < G_iNumberCount; i++)
{
scanf("%d", &G_iNumberList[i]);
}
G_iNumberStat[0] = -99999999;
G_iNumberStat[1] = G_iNumberList[0];
int maxLength = 1;
for (i = 1; i < G_iNumberCount; i++)
{
if (G_iNumberStat[maxLength] > G_iNumberList[i])
{
for (j = maxLength - 1; j >= 0; j--)
{
if (G_iNumberStat[j] < G_iNumberList[i])
{
if (G_iNumberStat[j + 1] > G_iNumberList[i])
{
G_iNumberStat[j + 1] = G_iNumberList[i];
}
}
}
}
else
{
maxLength++;
G_iNumberStat[maxLength] = G_iNumberList[i];
}
}
printf("%d\n", maxLength);
}
return 0;
}
...全文
400 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
pmars 2010-06-26
  • 打赏
  • 举报
回复
N*logN的想法就是利用二分法查找第i个数据的位置,之后交换!
弄一个数组存放最长递增子序列,当然这个数组里第j(j<i)个数是最小的(能到在这个位置最小的),这样变换就行了!
比如:
7

1 7 3 5 9 4 8
想法就是数组中先存1,之后来7的时侯二分查找这个数组返回2位置,之后存下7,这个时候数组中存放的是1 7,之后来3的时候查找数组返回2位置,将3存放到这个位置,这个时候存放的是1 3 。。。。
这样就能利用N*logN求出最大递增子序列的长度了!
绿色夹克衫 2010-06-26
  • 打赏
  • 举报
回复
fanster28_同志的代码一贯保持简洁优雅。

LZ如果还有问题的话,可以看看这个帖子。

http://topic.csdn.net/u/20100424/22/7a7b4a50-9110-4cf8-96ec-7fa728593b15.html
fanster28_ 2010-06-26
  • 打赏
  • 举报
回复
单调栈中查找元素用二分,你的没有二分复杂度依然是O(N*N)
fanster28_ 2010-06-26
  • 打赏
  • 举报
回复
nlog(n)就是贪心而已 维护一个单调栈,每次输入一个元素后,如果比栈顶大入栈,如果栈中没有此数,替换栈中刚好比这个大的

#include <iostream>
int s[10001],top,i,k,n,H,T,M;
int main() {
for(n;scanf("%d",&n)!=EOF;) {
scanf("%d",&s[top=0]);
for (i=1;i<n;++i) {
scanf("%d",&k);
if (k>s[top]) s[++top]=k;
else if (k<s[top]) {
for (H=-1,T=top+1;H+1!=T;) {
M=H+(T-H)/2;
if (s[M]<k) H=M;
else T=M;
}
s[T]=k;
}
}
printf("%d\n",top+1);
}
return 0;
}
gqjjqg 2010-06-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fanster28_ 的回复:]
代码结构太混乱了,最长上升子序列很清晰的啊


C/C++ code

#include <iostream>

int nums[10001],f[10001],i,j,n,ans;

int main() {
for(n;scanf("%d",&n)!=EOF;) {
for (i=1;i<=n;++i) {
sc……
[/Quote]

谢谢,你的方法我会的 O(N^2)的....
时间上消耗有点大...

我想写个O(NlogN)的..
我这里的思路是:

2个数组,一个存输入的数列,一个按照 子序列 长度 为下标 存储 子序列的最后一个数值...
按照读入一个个数列,比较第二个数组中的最后一个数值大小,不断更行第二个数组,直到获得最长的子序列.....貌似我想不出错在哪里...
fanster28_ 2010-06-26
  • 打赏
  • 举报
回复
代码结构太混乱了,最长上升子序列很清晰的啊


#include <iostream>

int nums[10001],f[10001],i,j,n,ans;

int main() {
for(n;scanf("%d",&n)!=EOF;) {
for (i=1;i<=n;++i) {
scanf("%d",nums+i);
f[i]=1;
}
for (ans=1,i=2;i<=n;++i) {
for (j=i-1;j>0;--j) if (nums[i]>nums[j]&&f[j]>=f[i])
f[i]=f[j]+1;
if (f[i]>ans) ans=f[i];
}
printf("%d\n",ans);
}
return 0;
}
gqjjqg 2010-06-26
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 fanster28_ 的回复:]
C/C++ code
#include <stdio.h>
int G_iNumberList[1000000];
int G_iNumberStat[1000000];
int G_iNumberCount;
int main()
{
while (1 == scanf("%d", &G_iNumberCount))
{
in……
[/Quote]

谢谢提醒,等于也不行....汗死...
我去试试2分,改进算法...
fanster28_ 2010-06-26
  • 打赏
  • 举报
回复
#include <stdio.h> 
int G_iNumberList[1000000];
int G_iNumberStat[1000000];
int G_iNumberCount;
int main()
{
while (1 == scanf("%d", &G_iNumberCount))
{
int i, j;
for (i = 0; i < G_iNumberCount; i++)
{
scanf("%d", &G_iNumberList[i]);
}
G_iNumberStat[0] = -99999999;
G_iNumberStat[1] = G_iNumberList[0];
int maxLength = 1;
for (i = 1; i < G_iNumberCount; i++)
{
if (G_iNumberStat[maxLength] > G_iNumberList[i])
{
for (j = maxLength - 1; j >= 0; j--)
{
if (G_iNumberStat[j] < G_iNumberList[i])
{
if (G_iNumberStat[j + 1] > G_iNumberList[i])
{
G_iNumberStat[j + 1] = G_iNumberList[i];
}
}
}
}
else if (G_iNumberStat[maxLength] < G_iNumberList[i]) //注意大于栈顶元素才入栈 等于也不行
{
maxLength++;
G_iNumberStat[maxLength] = G_iNumberList[i];
}
}
printf("%d\n", maxLength);
}
return 0;
}


友情提醒,你的算法还是O(n^2) 请注意采用二分查找
gqjjqg 2010-06-26
  • 打赏
  • 举报
回复
谢谢朋友们,我换个提问的方式,为什么我写的错误了?
错在哪里?
虽然分数不多,希望各位帮我找到原因谢谢!

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧