Problem Address:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1632
Problem Address:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1278
其实两道题是同一个题,都是LIS类型。
刚开始是做1278,但是出来后过不了,便试了一下1632,结果过了。
网上找了下原始版的LIS代码,看不出个所以然。
找JL帮忙,他给了个数据,没过。
我一看,把等号去掉,轻松就AC了。
结论就是,有些OJ的CASE很水= =(后来发现其实不是CASE水,而是我水……题意确实有点不同……)
经典的LIS自己可以去找下看看,代码如下:
#include<iostream>
using namespace std;
int a[1005];
int dp[1005];
int main()
{
int n,i,j,ans,max;
while(cin>>n&&n)
{
for(i=1;i<=n;i++)
cin>>a[i];
max=0;
for(i=1;i<=n;i++)
{
dp[i]=1;
for(j=1;j<=i-1;j++)
{
if(a[j]>=a[i]&&dp[i]<=dp[j]+1)
dp[i]=dp[j]+1;
}
if(dp[i]>max) max=dp[i];
}
cout<<max<<endl;
}
return 0;
}
我其实是之前看过了别人文章的介绍所以用了另一种方法。
他的那种是新建一个数组然后记录序列长度数,而我的是直接在原来的数据数组里操作。
初始序列长度为0。
对于每一个数都跟序列长度以内的数比较,如果刚好比某一个数大,则把它覆盖到上面去。
如果超出序列长度还没找到比他小的数,则把这个数添加到序列的尾部并使长度加一。
这个算法对比上一个可以节省很多对比的次数。
所以结果出来后是453MS和31MS的差距。
赞一下自己~也赞一下JL~。
以下贴代码:
#include <iostream>
using namespace std;
int main()
{
int ct[1005],num;
int n,i,x,j;
while(scanf("%d", &n)!=EOF)
{
if (n==0) break;
num = 0;
for (i=0; i<n; i++)
{
scanf("%d", &ct[i]);
}
for (i=0; i<n; i++)
{
x = ct[i];
for (j=0; j<num; j++)
{
if (x>=ct[j])//这里如果使用>=则为严格单调递减,否则为单调非递增
{
ct[j] = x;
break;
}
}
if (j==num)
{
ct[num] = x;
num++;
}
}
printf("%d/n", num);
}
return 0;
}
今天开始学习DP,不过乱找的几道题都看不出个所以然。哎~
继续努力啦!!