충남대학교 컴퓨터공학과 이영석 교수님의 "알고리즘" 강의 실습 내용입니다.
- 실습 문제들의 코드 위주로 구성되어 있습니다.
문제 1: 피보나치 수열
/**
* CNU week13 prob1
*
* Fibonacci
*/
#include <iostream>
#include <vector>
using namespace std;
// 정수 오버플로우를 방지하기 위함
#define uint uint64_t
int main() {
int N;
cin >> N;
// 모든 숫자를 0으로 초기화
vector<uint> cache(N + 1, 0);
// Fibonacci(1) = 1이므로
cache[1] = 1;
// Fibonacci(N)까지를 점화식을 이용해 계산함
for (int i = 2; i <= N; i++) {
cache[i] = cache[i - 1] + cache[i - 2];
}
// STDOUT
cout << cache[N] << endl;
return 0;
}문제 2: 배낭
/**
* CNU week13 prob2
*
* Knapsack
*/
#include <iostream>
#include <vector>
using namespace std;
int main() {
int C, N;
cin >> C >> N;
// 물품의 무게를 1-index로 저장함
vector<int> W(N + 1, 0);
for(int i = 1; i <= N; i++) {
cin >> W[i];
}
// 물품의 가치를 1-index로 저장함
vector<int> V(N + 1, 0);
for(int i = 1; i <= N; i++) {
cin >> V[i];
}
// cache[i번째 물품][무게제한 w] == 1번째 ~ i번째 물품까지 고려했을때 무게제한 w내에서의 최대 가치
vector<vector<int>> cache(N + 1, vector<int>(C + 1));
// 모든 물품 범위와 무게제한에 대해 최대 가치를 저장함
for(int i = 1; i <= N; i++) {
for(int w = 1; w <= C; w++) {
// 만약 물품 범위의 마지막 물품의 무게가 현재 무게제한보다 클 경우
if(W[i] > w) {
// 물품 범위의 마지막 물품을 가방에 넣지 않음
cache[i][w] = cache[i - 1][w];
// 만약 물품 범위의 마지막 물품의 무게가 현재 무게제한보다 작거나 같을 경우
} else {
// 마지막 물품을 가방에 넣었을때와 넣지 않았을때 중 가치가 큰것을 고름
cache[i][w] = max(V[i] + cache[i - 1][w - W[i]], cache[i - 1][w]);
}
}
}
// 주어진 물품 범위와 무게 제한에 대한 가치의 최고값 출력
cout << cache[N][C] << endl;
return 0;
}문제 3: 최장공통부분수열
/**
* CNU week13 prob3
*
* Longest Common Subsequence
*/
#include <iostream>
#include <vector>
using namespace std;
int main() {
string s1, s2;
cin >> s1 >> s2;
int N1, N2;
N1 = s1.size();
N2 = s2.size();
// cache[첫번째 문자열의 1-index i1][두번째 문자열의 1-index i2] ==
// 첫번째 문자열의 1 ~ i1의 범위와
// 두번째 문자열의 1 ~ i2의 범위를 고려한 LCS
vector<vector<int>> cache(N1 + 1, vector<int>(N2 + 1, 0));
// 모든 i1와 i2의 범위 조합에 대해 계산함
for(int i1 = 1; i1 <= N1; i1++) {
for(int i2 = 1; i2 <= N2; i2++) {
// 만일 0-index로 변환한 i1의 문자와 i2의 문자가 같을 경우
// 지금까지 이어져오던 LCS에 현재의 문자를 추가해야됨
// 지금까지 이어져오던 LCS Stream은 현재의 동일한 두 문자를 제외한 이전의 범위의 LCS Stream이다
// 따라서, 문자열 s1에 대한 1 ~ (i1 - 1)의 범위와
// 문자열 s2에 대한 1 ~ (i2 - 1)의 범위에서의 LCS길이에 1을 추가한 값이
// 1 ~ i1과 1 ~ i2의 범위에 대한 LCS의 길이가 됨
if(s1[i1 - 1] == s2[i2 - 1]) {
cache[i1][i2] = cache[i1 - 1][i2 - 1] + 1;
// 만일 두 문자가 같지 않은 경우
// 두 문자 각각을 제외했을때의 LCS 중 가장 긴것을 선택
} else {
cache[i1][i2] = max(cache[i1 - 1][i2], cache[i1][i2 - 1]);
}
}
}
cout << cache[N1][N2] << endl;
return 0;
}