๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ”Ž Algorithm/๐Ÿ’ป ๋ฌธ์ œ ํ’€์ด

[๋ฐฑ์ค€] 2629. ์–‘ํŒ” ์ €์šธ

by Seongpyo Hong 2021. 4. 1.

๋ฌธ์ œ

 

ํ’€์ด

์˜ค๋žœ๋งŒ์— ํ‘ธ๋Š” DP๋ฌธ์ œ์˜€๋‹ค. ๋จผ์ € ์ถ”๋ฅผ ๋„ฃ์—ˆ์„ ๋•Œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์ถ”์˜ ๋ฌด๊ฒŒ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ Cache๋ฐฐ์—ด์„ ์œ ์ง€ํ–ˆ๋‹ค.

์ด ๋•Œ ํ•ด๋‹น ์ถ”์— ๋Œ€ํ•ด ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ํ˜„์žฌ ์ถ”๋งŒ ๋„ฃ์€ ๊ฒฝ์šฐ
  2. ์ด์ „ ๋‹จ๊ณ„์—์„œ ๋งŒ๋“ค์—ˆ๋˜ ๋ฌด๊ฒŒ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ
  3. ์ด์ „ ๋‹จ๊ณ„์—์„œ ๋งŒ๋“ค์—ˆ๋˜ ๋ฌด๊ฒŒ์— ํ˜„์žฌ ์ถ”๋ฅผ ๋”ํ•˜๋Š” ๊ฒฝ์šฐ
  4. ์ด์ „ ๋‹จ๊ณ„์—์„œ ๋งŒ๋“ค์—ˆ๋˜ ๋ฌด๊ฒŒ์— ํ˜„์žฌ ์ถ”๋ฅผ ๋นผ๋Š” ๊ฒฝ์šฐ (๋ฌผ์ฒด์ชฝ์— ์ถ”๋ฅผ ๋†“๋Š” ๊ฒฝ์šฐ)

์ตœ์ข…์ ์œผ๋กœ ๋งˆ์ง€๋ง‰ ์ถ”๋ฅผ ๋„ฃ์—ˆ์„ ๋•Œ ๊ฐ€๋Šฅํ•œ ๋ฌด๊ฒŒ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค. 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	// Input ๋ฐ›๊ธฐ ์œ„ํ•œ Buffered Reader
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	// ์ถ”์˜ ๊ฐœ์ˆ˜ : N, ๋ฌด๊ฒŒ๋ฅผ ์ ค ๋ฌผ์ฒด์˜ ๊ฐœ์ˆ˜ : M
	static int N, M;
	// ์ถ”์˜ ์ง‘ํ•ฉ : src , ๋ฌผ์ฒด์˜ ์ง‘ํ•ฉ : dest
	static int[] src, dest;
	// ํ•ด๋‹น ์ธ๋ฑ์Šค์˜ ์ถ”๋ฅผ ํ†ตํ•ด ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฌด๊ฒŒ๋ฅผ ์ €์žฅ
	static boolean[][] cache = new boolean[30][40001];
	public static void main(String[] args) throws NumberFormatException, IOException {
		// ์ถ”์˜ ๊ฐœ์ˆ˜
		N = Integer.parseInt(br.readLine());
		// ์ถ” ๋ฐฐ์—ด ์ดˆ๊ธฐํ™”
		src = new int[N];
		// ์ถ” ๋ฐฐ์—ด ํ• ๋‹น
		String[] srcInput = br.readLine().split(" ");
		for (int i = 0; i < N; i++) {
			src[i] = Integer.parseInt(srcInput[i]);
		}
		
		// ๋ฌผ์ฒด์˜ ๊ฐœ์ˆ˜
		M = Integer.parseInt(br.readLine());
		// ๋ฌผ์ฒด ๋ฐฐ์—ด ์ดˆ๊ธฐํ™”
		dest = new int[M];
		// ๋ฌผ์ฒด ๋ฐฐ์—ด ํ• ๋‹น
		String[] destInput = br.readLine().split(" ");
		for (int i = 0; i < M; i++) {
			dest[i] = Integer.parseInt(destInput[i]);
		}
		
		// cache ๋ฐฐ์—ด ๊ฐ’ ํ• ๋‹น
		makeCache();
		
		// ์ถœ๋žต
		for (int i = 0; i < M; i++) {
			// ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฉด
			if (isMakable(dest[i]))
				System.out.print('Y' + " ");
			// ๋งŒ๋“ค ์ˆ˜ ์—†์œผ๋ฉด
			else
				System.out.print('N' + " ");
		}		
	}

	// ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฌด๊ฒŒ์ธ์ง€ ํƒ์ƒ‰
	private static boolean isMakable(int target) {
		// ๋งˆ์ง€๋ง‰ ์ถ”๊นŒ์ง€ ๊ณ ๋ คํ–ˆ์„ ๋•Œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์ธ์ง€ ํ™•์ธ
		return cache[N-1][target];
	}


	private static void makeCache() {
		// ์ด์ „ ์ตœ๋Œ€๊ฐ’์„ ๊ธฐ์–ตํ•˜๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜ => ํ˜„์žฌ ๋‹จ๊ณ„์—์„œ ์ตœ๋Œ€ ๋ฌด๊ฒŒ๋Š” ์ด์ „ ๋‹จ๊ณ„์—์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฌด๊ฒŒ์˜ ์ตœ๋Œ€๊ฐ’ + ํ˜„์žฌ ์ž์‹ ์˜ ๋ฌด๊ฒŒ
		int prevMax = src[0];
		// ์‹œ์ž‘ ๊ฐ’ ์ดˆ๊ธฐํ™” => 0๋ฒˆ idx๋Š” ์ž์‹ ์„ ๋„ฃ๋Š” ๊ฒฝ์šฐ๋งŒ ๊ฐ€๋Šฅ
		cache[0][src[0]] = true;
		
		// 1๋ฒˆ idx๋ถ€ํ„ฐ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฌด๊ฒŒ๋ฅผ ํƒ์ƒ‰
		for (int i = 1; i < N; i++) {
			// ํ˜„์žฌ ์ถ”์˜ ๋ฌด๊ฒŒ
			int curSrc = src[i];
			// ํ˜„์žฌ ์ถ”๋งŒ ๋„ฃ์—ˆ์„ ๋•Œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฌด๊ฒŒ
			cache[i][curSrc] = true;
			
			// ํ˜„์žฌ ์ถ”๋ฅผ ํ†ตํ•ด ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฌด๊ฒŒ์˜ ์ตœ๋Œ€๊ฐ’
			int curMax = 0;
			
			// ์ด์ „ ๋‹จ๊ณ„์—์„œ ๋งŒ๋“ค์—ˆ๋˜ ๋ฌด๊ฒŒ๋ฅผ ํ†ตํ•ด ํ˜„์žฌ ๋‹จ๊ณ„์—์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฌด๊ฒŒ ํƒ์ƒ‰ => ๋ชจ๋“  ๋ฌด๊ฒŒ๋ฅผ ๋Œ ํ•„์š”๊ฐ€ ์—†๊ณ  ์ด์ „ ๋‹จ๊ณ„์˜ ์ตœ๋Œ€๋ฌด๊ฒŒ ์ „๊นŒ์ง€๋งŒ ํƒ์ƒ‰ํ•˜๋ฉด ๋œ๋‹ค.
			for (int j = 1; j <= prevMax; j++) {
				// ์ด์ „์— ๋งŒ๋“ค ์ˆ˜ ์—†๋Š” ๋ฌด๊ฒŒ์ธ ๊ฒฝ์šฐ Skip
				if (!cache[i-1][j]) continue;
				// ์ด์ „ ๋ฌด๊ฒŒ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ (ํ˜„์žฌ ๋ฌด๊ฒŒ ์‚ฌ์šฉ X)
				cache[i][j] = true;
				// ์ด์ „ ๋ฌด๊ฒŒ + ํ˜„์žฌ ๋ฌด๊ฒŒ
				cache[i][j + curSrc] = true;
				// ์ด์ „ ๋ฌด๊ฒŒ - ํ˜„์žฌ ๋ฌด๊ฒŒ => ๋ฌด๊ฒŒ๋ฅผ ์ธก์ •ํ•˜๋ ค๋Š” ๋ฌผ์ฒด์ชฝ์— ์ถ”๋ฅผ ๋„ฃ๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ๊ฒฝ์šฐ
				cache[i][Math.abs(j - curSrc)] = true;
				// ์ตœ๋Œ€ ๋ฌด๊ฒŒ๋Š” ํ•ญ์ƒ ๋”ํ•œ ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ๋”ํ•œ ๊ฐ’์œผ๋กœ ๊ฐฑ์‹ 
				curMax = j + curSrc;
			}
			
			// ์ด์ „ ์ตœ๋Œ€๊ฐ’ ๊ฐฑ์‹ 
			prevMax = curMax;
		}
	}
}

๋Œ“๊ธ€