알고리즘/알고리즘 문제 풀이

[BOJ 20047] 동전 옮기기

GaeunLee 2021. 10. 3. 01:37

백준 20047

www.acmicpc.net/problem/20047

 

20047번: 동전 옮기기

입력은 표준입력을 사용한다. 첫 번째 줄에 나열된 동전 개수를 나타낸 양의 정수 n (3 ≤ n ≤ 10,000)이 주어진다. 다음 두 줄에 n 개의 동전이 나열된 상태인 S 와 T 가 각각 주어지며, 이 때 S와 T

www.acmicpc.net

손가락으로 짚은 두 동전을 편의상 Fcoin이라고 하자.

 

 

1. 문자열 S(Fcoin을 제외), T의 인덱스를 증가시키면서 비교하고, 달라지는 경우에 T와 Fcoin을 비교했다.

 

   그럴 경우 반례가 생긴다.

-> 문자열 S(Fcoin을 제외)에서 비교할 문자와 와 Fcoin이 같은 경우 어떤 경우로 체크해줘야 하는지 고려하지 않았다.

 

3
xxo
xox
0 2
ans : YES

 

 

2. dp로 풀 수 있다는 사실을 알고 다시 풀었다.

 

   dp[문자열의 인덱스][사용한 Fcoin의 개수]

 

점화식

dp[n][0] =  dp[n-1][0] && S,T비교

dp[n][1] = (dp[n-1][0] && T,Fcoin1비교) || (dp[n-1][1] && S,T비교)

dp[n][2] = (dp[n-1][1] && T,Fcoin2비교) || (dp[n-1][2] && S,T비교)

 

// dp[n-2][0], dp[n-1][0], dp[n-1][1]은 항상 0이기 때문에, 비교할 때 out of range를 피하기 위해 임의로 뒤에 두 공간을 채웠다.

#include <iostream>
#include <vector>
using namespace std;
vector<char> s, t;
bool dp[10001][3] = { false, };
char str[2];
int n;

int main() {
	cin >> n;

	for (int i = 0;i < n;i++) {
		char k;
		cin >> k;
		s.push_back(k);
	}
	for (int i = 0;i < n;i++) {
		char k;
		cin >> k;
		t.push_back(k);
	}
	int x, y;
	cin >> x >> y;

	str[0] = s[x]; str[1] = s[y];
	s.erase(s.begin() + x); s.erase(s.begin() + y - 1);
	s.push_back('n'); s.push_back('n'); //임의로 뒤에 채우기
	
	//초기화
	if (s[0] == t[0])
		dp[0][0] = true;
	if (t[0] == str[0])
		dp[0][1] = true;
        
	//점화식
	for (int i = 1;i < n;i++) {
		dp[i][0] = dp[i - 1][0] && (s[i] == t[i]);
		dp[i][1] = (dp[i - 1][0] && (str[0] == t[i])) || (dp[i - 1][1] && (s[i - 1] == t[i]));
		dp[i][2] = (dp[i - 1][1] && (str[1] == t[i])) || (dp[i - 1][2] && (s[i - 2] == t[i]));
	}

	//출력
	if (dp[n - 1][2])
		cout << "YES\n";
	else cout << "NO\n";
	
}

'알고리즘 > 알고리즘 문제 풀이' 카테고리의 다른 글

[BOJ 17626] Four Squares  (0) 2021.10.08