[白俊]12852号1制作2/Java,Python


Baekjoon Online Judge


algorithm practice


-問題を逐次解く


27.動的計画法と最短距離逆追跡


今まで最高価格と最低価格の最短距離しか見つからなかった今回は、実際のベストパスと最短パスを探してみましょう.
Java/Python

1.作成は1 2


12852号
出力1の最適解の問題

この問題が1つの整数Nを与えると,上記3つの演算を適切に用いて1が生成される.演算回数の最大値を使用する問題を出力します.
整数Xには、次の3つの演算があります.
1.Xを3で割って、3で割った.
2.Xを2で割り、2で割ります.
1を減らす.
  • Java
  • import java.io.*;
    import java.util.*;
    
    public class Main {  
    	static int N;
    	static int[] dp;
    	static final int INF = 1000000000;
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));   
    		StringBuilder sb = new StringBuilder();
            
    		N = Integer.parseInt(br.readLine()); 
    		dp = new int[N + 1];
            
    		Arrays.fill(dp, INF);
    		dp[N] = 0;
            
    		for(int i = N; i >= 1; i--){
    			// 현재 i위치에서 가는 최솟값
    			int minValue = dp[i] + 1;
    
    			if(i % 3 == 0) dp[i / 3] = Math.min(dp[i / 3], minValue);
    			if(i % 2 == 0) dp[i / 2] = Math.min(dp[i / 2], minValue);
                
    			dp[i - 1] = Math.min(dp[i - 1], minValue);
    		}        
    
    		sb.append(dp[1] + "\n");
            
    		int minValue = dp[1];
    		Stack<Integer> stack = new Stack<>();
    
    		for(int i = 1; i <= N; i++){
    			if(minValue == dp[i]){
    				stack.push(i);
    				
    				if(i*3 <= N && dp[i * 3] == minValue - 1) i = i*3 - 1;
    				else if(i*2 <= N && dp[i * 2] == minValue - 1) i = i*2 - 1;
    				
    				minValue--;
    			}
    		}
            
    		while(!stack.isEmpty()) {
    			sb.append(stack.pop() + " ");
    		}
            
    		bw.write(sb.toString());
            
    		bw.flush();
    		br.close();
    		bw.close();
    	}	
    }
  • Python
  • import sys
    
    N = int(sys.stdin.readline())
    dp = [[0, []] for _ in range(N + 1)] #[최솟값, 경로 리스트]
    dp[1][0] = 0 
    dp[1][1] = [1]
    
    for i in range(2, N + 1):
    	
        #f(x-1) + 1   
        dp[i][0] = dp[i-1][0] + 1
        dp[i][1] = dp[i-1][1] + [i]
        
        #f(x//3) + 1   
        if i % 3 == 0 and dp[i//3][0] + 1 < dp[i][0]:
            dp[i][0] = dp[i//3][0] + 1
            dp[i][1] = dp[i//3][1] + [i]
    
    	#f(x//2) + 1   
        if i % 2 == 0 and dp[i//2][0] + 1 < dp[i][0]:
            dp[i][0] = dp[i//2][0] + 1
            dp[i][1] = dp[i//2][1] + [i]
            
    print(dp[N][0])
    for i in dp[N][1][::-1]: # 역순 출력
        print(i, end=' ')