ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Algo RhythmπŸ•ΊπŸ’ƒ] BOJ 17528. Two Machines
    Algo RhythmπŸ•ΊπŸ’ƒ/BOJ 2020. 8. 26. 21:06

    πŸ“š 문제 μ„€λͺ…

    μŠ€μΌ€μ€„λ§ μ΅œμ ν™” νšŒμ‚¬μΈ SOPT 에 μ™„λ£Œν•΄μ•Ό ν•  n개의 μž‘μ—… t1, t2, ..., tn μ΄ μžˆλ‹€. SOPT νšŒμ‚¬λŠ” 두 λŒ€μ˜ λ¨Έμ‹  A μ™€ B λ₯Ό λ³΄μœ ν•˜κ³  μžˆλ‹€. 각 μž‘μ—… tiλ₯Ό μ™„λ£Œν•˜κΈ° μœ„ν•΄ SOPT λŠ” λ¨Έμ‹  A μ™€ B λ‘˜ 쀑에 였직 ν•˜λ‚˜λ₯Ό 선택할 수 μžˆλ‹€. μž‘μ—… tiλ₯Ό μ™„λ£Œν•˜κΈ° μœ„ν•΄ λ¨Έμ‹  Aλ₯Ό μ„ νƒν•˜λ©΄ aiμ‹œκ°„μ΄ 걸리고 λ¨Έμ‹  Bλ₯Ό μ„ νƒν•˜λ©΄ bi μ‹œκ°„이 κ±Έλ¦°λ‹€. 각 머신은 μ–΄λŠ μˆœκ°„μ— μ΅œλŒ€ ν•˜λ‚˜μ˜ μž‘μ—…λ§Œ μˆ˜ν–‰ν•  수 있으며, ν•œ μž‘μ—…μ΄ μ‹œμž‘λ˜λ©΄ κ·Έ μž‘μ—…μ„ μ™„λ£Œν•˜κΈ° μ „κΉŒμ§€ λ‹€λ₯Έ μž‘μ—…μ„ κ·Έ λ¨Έμ‹ μ—μ„œ μˆ˜ν–‰ν•  수 μ—†λ‹€. SOPT λŠ” λͺ¨λ“  μž‘μ—…μ„ μ™„λ£Œν•˜κΈ° μœ„ν•œ μ΅œμ†Œμ˜ μ™„λ£Œ μ‹œκ°„μ„ κ΅¬ν•˜κ³ μž ν•œλ‹€.

    예λ₯Ό λ“€μ–΄, μ„Έ 개의 μž‘μ—…μ΄ t1, t2, t3κ°€ μ£Όμ–΄μ Έ 있고 a1 = 2, b1 = 3, a2 = 5, b2 = 3, a3 = 2, b3 = 7라고 ν•˜μž. μ™„λ£Œ μ‹œκ°„μ„ μ΅œμ†Œν™”ν•˜κΈ° μœ„ν•΄μ„œλŠ” μž‘μ—… t1, t3λŠ” λ¨Έμ‹  A에, μž‘μ—… t2λŠ” λ¨Έμ‹  B에 ν• λ‹Ήν•œλ‹€. λ¨Έμ‹  AλŠ” μž‘μ—… t1, t3λ₯Ό μ™„λ£Œν•˜λŠ”λ° 2 + 2 = 4 μ‹œκ°„μ΄ 걸리고 λ¨Έμ‹  BλŠ” μž‘μ—… t2λ₯Ό μ™„λ£Œν•˜λŠ”λ° 3 μ‹œκ°„μ΄ κ±Έλ¦°λ‹€. λ”°λΌμ„œ μ΅œμ†Œ μ™„λ£Œ μ‹œκ°„μ€ 4 μ‹œκ°„μ΄ λœλ‹€. n개의 μž‘μ—… t1t2, ..., tn κ³Ό 각 λ¨Έμ‹ μ—μ„œ 각 μž‘μ—…λ“€μ„ μˆ˜ν–‰ν•˜λŠ” 데 κ±Έλ¦¬λŠ” μ‹œκ°„λ“€μ΄ μ£Όμ–΄μ§ˆ λ•Œ, λͺ¨λ“  μž‘μ—…λ“€μ„ μ™„λ£Œν•˜κΈ° μœ„ν•΄ κ±Έλ¦¬λŠ” μ‹œκ°„μ˜ μ΅œμ†Ÿκ°’μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

    μž…λ ₯
    μž…λ ₯은 ν‘œμ€€μž…λ ₯을 μ‚¬μš©ν•œλ‹€. 첫 번째 쀄에 μž‘μ—…μ˜ 개수λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ–‘μ˜ μ •μˆ˜ n (1 ≤ n ≤ 250)이 주어진닀. λ‹€μŒ n개의 μ€„μ—μ„œ i번째 μ€„μ—λŠ” 두 개의 μ •μˆ˜ aibi (1 ≤ aibi ≤ 250)κ°€ 주어진닀. μ—¬κΈ°μ„œ ai와 biλŠ” 각각 μž‘μ—… tiλ₯Ό λ¨Έμ‹  A와 Bμ—μ„œ μ™„λ£Œν•˜λŠ”λ° κ±Έλ¦¬λŠ” μ‹œκ°„μ΄λ‹€.
    좜λ ₯
    좜λ ₯은 ν‘œμ€€μΆœλ ₯을 μ‚¬μš©ν•œλ‹€. λͺ¨λ“  μž‘μ—… t1t2, ..., tn을 μ™„λ£Œν•˜κΈ° μœ„ν•œ μ΅œμ†Œμ˜ μ™„λ£Œμ‹œκ°„μ„ ν•œ 쀄에 좜λ ₯ν•œλ‹€.

     

    🎯 μ–΄λ–»κ²Œ ν’€μ—ˆλ‚˜

    import java.util.Scanner;
    
    public class BOJ_17528 {
    	
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		int n = sc.nextInt();
    		int[] a = new int[n + 1];
    		int[] b = new int[n + 1];
    		int[] ab = new int[n + 1];
    		int[][] dpA, dpB;
    		int totalA = 0 , totalB = 0;
    		int ans;
    		
    		// init
    		for(int i = 1; i <= n; i++) {
    			a[i] = sc.nextInt();
    			b[i] = sc.nextInt();
    			ab[i] = a[i] + b[i];
    			totalA += a[i];
    			totalB += b[i];
    		}
    		
    		sc.close();
    		
    		dpA = new int[n + 1][totalA + 1];
    		dpB = new int[n + 1][totalB + 1];
    		
    		// dpA
    		for(int i = 1; i <= n; i++) {
    			for(int j = 1; j <= totalA; j++) {
    				if(ab[i] <= j) {
    					dpA[i][j] = Math.max(dpA[i - 1][j], dpA[i - 1][j - ab[i]] + a[i]);
    				}
    				else {
    					dpA[i][j] = dpA[i - 1][j];
    				}
    			}
    		}
    		
    		// dpB
    		for(int i = 1; i <= n; i++) {
    			for(int j = 1; j <= totalB; j++) {
    				if(ab[i] <= j) {
    					dpB[i][j] = Math.max(dpB[i - 1][j], dpB[i - 1][j - ab[i]] + b[i]); 
    				}
    				else {
    					dpB[i][j] = dpB[i - 1][j];
    				}
    			}
    		}
    		
    		ans = Math.min(totalA - dpA[n][totalA], totalB - dpB[n][totalB]);
    		
    		System.out.println(ans);
    	}
    
    }

     

    🧐 μ™œ μ €λ ‡κ²Œ ν’€μ—ˆλ‚˜

    사싀 이 λ¬Έμ œλŠ” μ•„λž˜ λΈ”λ‘œκ·Έμ˜ 도움을 λ°›μ•„μ„œ ν•΄κ²°ν–ˆλ‹€.

    https://sbrus1213.tistory.com/3#problemL

     

    이 문제λ₯Ό ν’€κΈ° μ „ λ¨Όμ € 생각해야 ν•  것은 "μž‘μ—… μ™„λ£Œ μ‹œκ°„μ΄ μ΅œμ†Œκ°€ 되기 μœ„ν•΄μ„œλŠ” A의 μˆ˜ν–‰ μ‹œκ°„κ³Ό B의 μˆ˜ν–‰ μ‹œκ°„μ˜ 차이가 μ΅œμ†Œκ°€ λ˜μ–΄μ•Ό ν•œλ‹€"λŠ” 것이닀.

    이런 경우 μš°λ¦¬λŠ” λ‹€μŒκ³Ό 같은 두 가지 μ‹œλ‚˜λ¦¬μ˜€λ₯Ό 생각할 수 μžˆλ‹€.

     

    μ‹œλ‚˜λ¦¬μ˜€ 1 : A의 μˆ˜ν–‰μ‹œκ°„μ΄ B의 μˆ˜ν–‰μ‹œκ°„λ³΄λ‹€ ν¬κ±°λ‚˜ κ°™κ³  λ‘˜μ˜ 차이가 μ΅œμ†ŒμΈ 경우
    μ‹œλ‚˜λ¦¬μ˜€ 2 : B의 μˆ˜ν–‰μ‹œκ°„μ΄ A의 μˆ˜ν–‰μ‹œκ°„λ³΄λ‹€ ν¬κ±°λ‚˜ κ°™κ³  λ‘˜μ˜ 차이가 μ΅œμ†ŒμΈ 경우

     

    첫번째 μ‹œλ‚˜λ¦¬μ˜€μ˜ 경우 μž‘μ—… μ™„λ£Œ μ‹œκ°„μ€ A의 μˆ˜ν–‰ μ‹œκ°„κ³Ό κ°™κ³  λ‘λ²ˆμ§Έ μ‹œλ‚˜λ¦¬μ˜€μ˜ 경우 B의 μˆ˜ν–‰ μ‹œκ°„κ³Ό 같을 것이닀. μ—¬κΈ°μ„œ μš°λ¦¬λŠ” 첫번째 μ‹œλ‚˜λ¦¬μ˜€μ˜ κ²½μš°μ—λŠ” A의 μˆ˜ν–‰μ‹œκ°„λ§Œ, λ‘λ²ˆμ§Έ μ‹œλ‚˜λ¦¬μ˜€μ˜ κ²½μš°μ—λŠ” B의 μˆ˜ν–‰μ‹œκ°„λ§Œ μ€‘μš”ν•˜λ‹€λŠ” 사싀을 μ•Œ 수 μžˆλ‹€.

     

    μ—¬κΈ°κΉŒμ§€ λ„λ‹¬ν–ˆμœΌλ©΄ μ‹œλ‚˜λ¦¬μ˜€λ₯Ό λ³΄λŠ” 관점을 쑰금 λ°”κΎΈλŠ” 것이 μ–΄λ–¨κΉŒ?

    μ‹œλ‚˜λ¦¬μ˜€ 1의 경우 λͺ¨λ“  μž‘μ—…μ„ Aκ°€, μ‹œλ‚˜λ¦¬μ˜€ 2의 경우 λͺ¨λ“  μž‘μ—…μ„ Bκ°€ μˆ˜ν–‰ν•œλ‹€κ³  κ°€μ •ν•΄λ³΄μž.

    μ‹œλ‚˜λ¦¬μ˜€ 1의 경우 A의 μˆ˜ν–‰μ‹œκ°„μ΄ B의 μˆ˜ν–‰μ‹œκ°„λ³΄λ‹€ ν¬κ±°λ‚˜ κ°™κ³  λ‘˜μ˜ 차이가 μ΅œμ†Œκ°€ 되기 μœ„ν•΄μ„œλŠ” Aκ°€ λ‹΄λ‹Ήν•˜κ³  μžˆλŠ” λͺ¨λ“  μž‘μ—…λ“€ 쀑 일뢀λ₯Ό Bκ°€ μˆ˜ν–‰ν•΄μ•Ό ν•œλ‹€. 이 λ•Œ 선택해야 ν•˜λŠ” μž‘μ—…λ“€μ€ "Bκ°€ μˆ˜ν–‰ν•  λ•Œ A의 μˆ˜ν–‰μ‹œκ°„μ΄ κ°€μž₯ 많이 κ°μ†Œν•˜λŠ”" μž‘μ—…λ“€μ΄μ–΄μ•Ό ν•œλ‹€. 즉, κ°€μž₯ λ§Žμ€ A의 μˆ˜ν–‰ μ‹œκ°„μ„ κ°€μ Έμ˜€λŠ” 것이 졜적의 μž‘μ—…μ΄λ‹€. κ·Έλ ‡λ‹€λ©΄ μž‘μ—… μ™„λ£Œ μ‹œκ°„μ€ ( λͺ¨λ“  μž‘μ—…μ„ Aκ°€ μˆ˜ν–‰ν•  λ•Œ κ±Έλ¦¬λŠ” μ‹œκ°„ ) - ( κ°μ†Œμ‹œν‚¬ 수 μžˆλŠ” A μˆ˜ν–‰μ‹œκ°„μ˜ μ΅œλŒ“κ°’ ) 이닀. μ‹œλ‚˜λ¦¬μ˜€ 2의 κ²½μš°λŠ” λ°˜λŒ€λ‘œ μƒκ°ν•˜λ©΄ λœλ‹€.

     

    μ—¬κΈ°κΉŒμ§€ 였면 μš°λ¦¬λŠ” 이 λ¬Έμ œκ°€ 0-1 Knapsack problemκ³Ό λΉ„μŠ·ν•œ λͺ¨μ–‘μƒˆλ₯Ό κ°–μΆ”μ—ˆλ‹€λŠ” 사싀을 μ•Œ 수 μžˆλ‹€. 더 μžμ„Ένžˆ λ§ν•˜λ©΄ 이 λ¬Έμ œλŠ” λ‹€μŒκ³Ό 같이 0-1 Knapsack problemκ³Ό λŒ€μ‘ν•œλ‹€. (μ•„λž˜ μ˜ˆλŠ” μ‹œλ‚˜λ¦¬μ˜€ 1을 λ°”νƒ•μœΌλ‘œ μž‘μ„±ν•œ 것이닀.)

     

    ( item의 개수 ) = ( task의 개수 )

    ( knapsack에 담을 수 μžˆλŠ” 무게 ) = ( Aκ°€ λͺ¨λ“  μž‘μ—…μ„ λ‹΄λ‹Ήν•  λ•Œ κ±Έλ¦¬λŠ” μˆ˜ν–‰ μ‹œκ°„ )

    ( item의 무게 ) = ( Aκ°€ i번째 taskλ₯Ό μˆ˜ν–‰ν•  λ•Œ κ±Έλ¦¬λŠ” μ‹œκ°„ + Bκ°€ i번째 taskλ₯Ό μˆ˜ν–‰ν•  λ•Œ κ±Έλ¦¬λŠ” μ‹œκ°„ )

    ( item의 κ°€μΉ˜ ) = ( Aκ°€ i번째 taskλ₯Ό μˆ˜ν–‰ν•  λ•Œ κ±Έλ¦¬λŠ” μ‹œκ°„ )

     

    μ΄λ•Œ μ™œ item의 λ¬΄κ²Œκ°€ Aκ°€ i번째 taskλ₯Ό μˆ˜ν–‰ν•  λ•Œ κ±Έλ¦¬λŠ” μ‹œκ°„ + Bκ°€ i번째 taskλ₯Ό μˆ˜ν–‰ν•  λ•Œ κ±Έλ¦¬λŠ” μ‹œκ°„μ™€ λŒ€μ‘ν•˜λŠ”μ§€ μ§κ΄€μ μœΌλ‘œ μ΄ν•΄λ˜μ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€ (λ‚˜λŠ” 이것이 μ΄ν•΄λ˜μ§€ μ•Šμ•„ μ˜€λž˜λ™μ•ˆ ν—€λ§Έλ‹€). μ΄μœ λŠ” κ°„λ‹¨ν•˜λ‹€. ν•œ μž‘μ—…μ„ μ‹€ν–‰ν•  λ•Œ κ±Έλ¦¬λŠ” A의 μˆ˜ν–‰ μ‹œκ°„μ„ κ°μ†Œμ‹œν‚¨λ‹€λŠ” 것은 같은 μž‘μ—…μ„ μ‹€ν–‰ν•  λ•Œ κ±Έλ¦¬λŠ” B의 μˆ˜ν–‰ μ‹œκ°„μ„ λŠ˜λ¦°λ‹€λŠ” 말과 κ°™λ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— Aκ°€ λͺ¨λ“  μž‘μ—…μ„ λ‹΄λ‹Ήν•  λ•Œ κ±Έλ¦¬λŠ” μˆ˜ν–‰ μ‹œκ°„ jλŠ” ν•œ μž‘μ—…μ„ λ‹΄λ‹Ήν•  λ•Œ κ±Έλ¦¬λŠ” A의 μˆ˜ν–‰μ‹œκ°„κ³Ό B의 μˆ˜ν–‰μ‹œκ°„μ˜ 합보닀 ν¬κ±°λ‚˜ 같을 λ•Œ i번째 μž‘μ—…μ„ μˆ˜ν–‰ν•  λ•Œ κ±Έλ¦¬λŠ” A둜 μˆ˜ν–‰ν•  λ•Œ κ±Έλ¦¬λŠ” μ‹œκ°„μ„κ°μ†Œν• μ§€ 말지(item을 ν¬ν•¨ν•˜μ§€ 말지)λ₯Ό κ²°μ •ν•  수 μžˆλ‹€.

    μ‹œλ‚˜λ¦¬μ˜€ 1, μ‹œλ‚˜λ¦¬μ˜€ 2λ₯Ό 각각 0-1 Knapsack problem으둜 κ΅¬ν˜„ν•΄μ„œ 각 μ‹œλ‚˜λ¦¬μ˜€ λ§ˆλ‹€ μž‘μ—… μ™„λ£Œ μ‹œκ°„μ„ κ΅¬ν•œ λ’€ λ‘˜ 쀑 더 μž‘μ€ 것을 κ΅¬ν•˜λ©΄ 그것이 닡이 λœλ‹€.

     

    πŸ“– 무엇을 λ°°μ› λ‚˜

    μƒκ°ν•˜λŠ” νž˜μ„ κΈ°λ₯΄μž!

    λŒ“κΈ€

Designed by Tistory.