LIS の長さを計算する
-
int s [5]; // sequence を保存するための配列
-
int array [5]; // x 番目の値は sequence: s [0]~s [x] の LIS の長さ
-
int LIS()
-
{
-
// 初期化、各数字は長さ 1 の部分列そのものである
-
for (int i=0; i<5; i++) array[i] = 1;
-
// LIS
-
for (int i=0; i<5; i++)
-
for (int j=i+1; j<5; j++) // s [i] の後に続く数字を探す
-
if (s [j] > s [i]) // 接続可能なら、長さを増やす
-
array[j] = max(array[j], array[i] + 1);
-
// array 中の最大値が LIS の長さである
-
int ans = 0;
-
for (int i=0; i<5; i++)
-
ans = max(ans, array[i]);
-
return ans;
-
}
LIS を見つける
-
int s[5];
-
int array[5];
-
int prev [5]; // prev [x] は s [x] がどの位置の数字の後に接続されているかを記録する
-
// 前に数字がなければ - 1 を記録する
-
int LIS()
-
{
-
for (int i=0; i<5; i++) array[i] = 1;
-
// -1 はこの数字が他の数字の後に接続されていないことを示す
-
for (int i=0; i<5; i++) prev[i] = -1;
-
for (int i=0; i<5; i++)
-
for (int j=i+1; j<5; j++)
-
if (s[j] > s[i])
-
if (array[i] + 1 > array[j])
-
{
-
array[j] = array[i] + 1;
-
prev [j] = i; // s [j] は s [i] の後に接続される
-
}
-
int ans = 0, pos = 0;
-
for (int i=0; i<5; i++)
-
if (ans > array[i])
-
{
-
ans = array[i];
-
pos = i;
-
}
-
print_LIS (pos); // 1 つの LIS を出力する
-
return ans;
-
}
-
// 再帰版
-
void print_LIS(int x)
-
{
-
if (prev[x] != -1) print_LIS(prev[x]);
-
cout << seq[x] << " ";
-
}
-
// ループ版だが、順序は逆である。
-
void print_LIS(int x)
-
{
-
for (; prev[x] != -1; x = prev[x])
-
cout << seq[x] << " ";
-
}