1. LIS 의 Length 구하기
2. LIS 의 Count 구하기
3. K 번쨰 LIS 구하기
Dynamic Programming Technics 로 들어오니 넘 어렵다...
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAX_N = 500;
const int MAX_K = 2000000000 + 100;
int N = 0, K = 0;
vector<int> nums, kLis;
int cacheLen[MAX_N + 1];
int cacheCnt[MAX_N + 1];
int lisLength(int start);
int lisCount(int start);
void reconstruct(int start, int skip);
int main()
{
int caseNum;
cin >> caseNum;
for (int cIter = 0; cIter < caseNum; cIter++)
{
// Read inputs
cin >> N >> K;
// Initialize
nums.clear();
kLis.clear();
for (int i = 0; i < MAX_N; i++)
{
cacheLen[i] = -1;
cacheCnt[i] = -1;
}
int buf = 0;
for (int i = 0; i < N; i++)
{
cin >> buf;
nums.push_back(buf);
}
// Process
lisLength(-1);
lisCount(-1);
reconstruct(-1, K - 1);
// Output
cout << "[ CASE " << cIter + 1 << " ]" << endl;
cout << "( LIS Length ) ";
for (int i = 0; i < N + 1; i++)
cout << cacheLen[i] << " ";
cout << endl;
cout << "( LIS Count ) ";
for (int i = 0; i < N + 1; i++)
cout << cacheCnt[i] << " ";
cout << endl;
cout << "( KLIS members ) ";
for (auto k : kLis)
{
cout << k << " ";
}
cout << endl << endl;
}
}
// Get LIS length from nums[start]
int lisLength(int start)
{
int &ret = cacheLen[start + 1];
if (start == N - 1) return ret = 1;
if (ret != -1) return ret;
ret = 1;
for (int next = start + 1; next < N; next++)
if (start == -1 || nums[start] < nums[next])
ret = max(ret, lisLength(next) + 1);
return ret;
}
// Get LIS count from nums[start]
int lisCount(int start)
{
int &ret = cacheCnt[start + 1];
if (lisLength(start) == 1) return ret = 1;
if (ret != -1) return ret;
ret = 0;
for (int next = start + 1; next < N; next++)
if ((start == -1 || nums[start] < nums[next]) && lisLength(start) == lisLength(next) + 1)
ret = min(ret + lisCount(next), MAX_K);
return ret;
}
// Get K th LIS
void reconstruct(int start, int skip)
{
if (start != -1) kLis.push_back(nums[start]);
vector<pair<int, int>> followers;
for (int next = start + 1; next < N; next++)
if ((start == -1 || nums[start] < nums[next]) && lisLength(start) == lisLength(next) + 1)
followers.push_back(make_pair(nums[next], next));
sort(followers.begin(), followers.end());
for (int i = 0; i < followers.size(); i++)
{
int idx = followers[i].second;
int cnt = lisCount(idx);
if (cnt <= skip)
{
skip -= cnt;
}
else
{
reconstruct(idx, skip);
break;
}
}
}반응형
'Algorithm > Dynamic Programming Technics' 카테고리의 다른 글
| PACKING (0) | 2019.02.12 |
|---|
KlisInput.txt