Wiki OI 1044迎撃ミサイル
1189 ワード
タイトルリンク:http://wikioi.com/problem/1044/
アルゴリズムと構想:
問題の意味をよく理解すると、実際には最長上昇サブシーケンスと最長下降サブシーケンスを求めます.
シーケンス全体を順次巡回し、最初の数から現在の数までの最長上昇サブシーケンスを求めるたびに、
最後の数字まで遍歴し、dp配列の中で最大のそれがシーケンス全体の最長上昇サブシーケンスである.
シーケンス1−iの最長上昇サブシーケンスの長さをdp[i]=max(dp[j])+1,(j∈[1,i−1])で格納する.
明らかにdp[1]=1であり,i=2から後の要素を遍歴すればよい.
アルゴリズムと構想:
問題の意味をよく理解すると、実際には最長上昇サブシーケンスと最長下降サブシーケンスを求めます.
シーケンス全体を順次巡回し、最初の数から現在の数までの最長上昇サブシーケンスを求めるたびに、
最後の数字まで遍歴し、dp配列の中で最大のそれがシーケンス全体の最長上昇サブシーケンスである.
シーケンス1−iの最長上昇サブシーケンスの長さをdp[i]=max(dp[j])+1,(j∈[1,i−1])で格納する.
明らかにdp[1]=1であり,i=2から後の要素を遍歴すればよい.
#include<stdio.h>
#include<string.h>
int n = 0, dp1[100005], dp2[100005];
int a[100005];
int DP1(int len)
{
int i, j, ans = 1, Max = 0;
dp1[1] = 1;
for(i = 2; i <= len; i++)
{
Max = 0;
for(j = 1; j < i; j++)
{
if(dp1[j] > Max && a[j] > a[i])
Max = dp1[j];
}
dp1[i] = Max + 1;
if(dp1[i] > ans)
ans = dp1[i];
}
return ans;
}
int DP2(int len)
{
int i, j, ans = 1, Max = 0;
dp2[1] = 1;
for(i = 2; i <= len; i++)
{
Max = 0;
for(j = 1; j < i; j++)
{
if(dp2[j] > Max && a[j] < a[i])
Max = dp2[j];
}
dp2[i] = Max + 1;
if(dp2[i] > ans)
ans = dp2[i];
}
return ans;
}
int main()
{
while(scanf("%d", &a[++n]) != EOF);
printf("%d
", DP1(n - 1));
printf("%d
", DP2(n - 1));
return 0;
}