CodingTest/Java

BOJ_1954 : ν™”ν•™μ‹€ν—˜

Soom_1n 2023. 2. 10. 09:45

πŸ‘‰ 문제링크

 

1954번: ν™”ν•™μ‹€ν—˜

μš°λ¦¬μ—κ²ŒλŠ” nκ°€μ§€ μ’…λ₯˜μ˜ ν™”ν•™ μ‹œμ•½ t1, t2, ..., tnκ³Ό M mg의 μš©μ•‘μ΄ μžˆλ‹€. 이 μš©μ•‘ 쀑 x mg을 μ‹œμ•½ ti에 λ„£μœΌλ©΄ aix+bi만큼의 μ–΄λ–€ κ°€μŠ€κ°€ λ°œμƒν•œλ‹€κ³  ν•œλ‹€. μ‹œμ•½μ— 넣을 수 μžˆλŠ” μš©μ•‘μ˜ 양은 μžμ—°μˆ˜μ΄

www.acmicpc.net



πŸ”Έ 문제 뢄석 πŸ”Έ

  • n μ’…λ₯˜μ˜ ν™”ν•™ μ‹œμ•½ t1, t2, ..., tn의 정보 ai와 bi, 그리고 M mg의 μš©μ•‘μ΄ μ£Όμ–΄μ§„λ‹€.
    • μš©μ•‘ 쀑 x mg을 μ‹œμ•½ ti 에 λ„£μœΌλ©΄ ai*x+bi 만큼의 κ°€μŠ€κ°€ λ°œμƒν•œλ‹€.
    • n개의 ν™”ν•™ μ‹œμ•½ λͺ¨λ‘ 같은 μ–‘μ˜ κ°€μŠ€λ₯Ό λ°œμƒμ‹œν‚¬ 수 있으면 κ°€μŠ€ 양을 좜λ ₯ν•˜κ³ , 그럴 수 μ—†μœΌλ©΄ 0을 좜λ ₯ν•œλ‹€.
    • μš©μ•‘μ΄ λ‚¨μœΌλ©΄ μ•ˆλœλ‹€.
  • μš©μ•‘μ˜ μ–‘ x mg 을 1λΆ€ν„° λŠ˜λ €κ°€λ©° μš©μ•‘λ“€μ— 넣어보고 같은 μ–‘μ˜ κ°€μŠ€κ°€ λ°œμƒν•˜λŠ” κ²½μš°κ°€ μžˆλŠ”μ§€ λͺ¨λ‘ 확인해야 ν•œλ‹€.
    • 경우의 수 확인 쀑, λͺ¨λ‘ 같은 μ–‘μ˜ κ°€μŠ€κ°€ λ°œμƒν•˜λŠ” 경우λ₯Ό 찾으면 κ·Έ κ°€μŠ€ 양을 좜λ ₯ν•˜κ³  μ’…λ£Œν•œλ‹€.
    • λκΉŒμ§€ 탐색해도 같은 μ–‘μ˜ κ°€μŠ€κ°€ λ°œμƒν•˜λŠ” κ²½μš°κ°€ μ—†μœΌλ©΄ 0을 좜λ ₯ν•œλ‹€.

πŸ”Έ μ½”λ“œ πŸ”Έ

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

public class Main {
    static int n, m;
    static int[] a;
    static int[] b;

    private static boolean recursion(int idx, int ml, int befor_gas) {
        if (idx == n) {
            return ml == 0;
        }

        for (int i = 1; i <= ml-(n-idx-1); i++) {
            int now_gas = a[idx]*i+b[idx];
            if (now_gas == befor_gas && recursion(idx+1, ml - i, befor_gas)) {
                return true;
            } else if (now_gas > befor_gas) {
                break;
            }
        }
        return false;
    }

    public static void main(String args[]) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());

        a = new int[n];
        b = new int[n];

        for (int i = 0; i < n; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            a[i] = Integer.parseInt(st.nextToken());
            b[i] = Integer.parseInt(st.nextToken());
        }

        m = Integer.parseInt(br.readLine());

        int answer = 0;
        for (int i = 1; i <= m - n + 1; i++) {
            int gas = a[0]*i+b[0];
            if (recursion(1, m-i, gas)) {
                answer = gas;
                break;
            }
        }
        System.out.println(answer);
    }
}

πŸ”Έ μ½”λ“œ 해석 πŸ”Έ

  • main λ©”μ„œλ“œμ—μ„œ n개의 μ‹œμ•½ 정보와 μš©μ•‘μ˜ μ–‘ m을 μž…λ ₯λ°›λŠ”λ‹€.
  • μš©λŸ‰ m을 1λΆ€ν„° m-(n-1) κΉŒμ§€ ν‚€μ›Œκ°€λ©° κ³„μ‚°ν•œλ‹€.
    • recursion λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ³ , trueκ°€ λ°˜ν™˜ 되면 정닡에 gasλ₯Ό μ €μž₯ν•˜κ³  λ°˜λ³΅μ„ μ’…λ£Œν•œλ‹€.
  • recursion λ©”μ„œλ“œλŠ” (ν˜„μž¬ κ³ λ₯Έ μ‹œμ•½ 수 idx, 남은 μš©μ•‘ ml, 이전에 λ‚˜μ˜¨ κ°€μŠ€ befor_gas) λ₯Ό 인자둜 λ°›μœΌλ©΄ ture,falseλ₯Ό λ°˜ν™˜ν•œλ‹€.
    • idxκ°€ n이 되면, 남은 μš©μ•‘μ΄ 0이면 ture, μ•„λ‹ˆλ©΄ falseλ₯Ό λ°˜ν™˜ν•œλ‹€. (μš©μ•‘μ΄ λ‚¨μœΌλ©΄ μ•ˆλœλ‹€)
    • forλ¬Έμ—μ„œλŠ” idx번째 μ‹œμ•½μ— 넣을 μš©μ•‘μ„ 1λΆ€ν„° ml-(n-idx-1) κΉŒμ§€ λ„£μ–΄λ³Έλ‹€.
      • λ‚˜μ˜¨ κ°€μŠ€ now_gasκ°€ 이전 κ°€μŠ€ befor_gas와 κ°™μœΌλ©΄, λ‹€μ‹œ recursion λ©”μ„œλ“œμ— λ‹€μŒ μ‹œμ•½μ„ ν™•μΈν•œλ‹€.
      • trueκ°€ λ°˜ν™˜ 되면, λ˜‘κ°™μ΄ trueλ₯Ό λ°˜ν™˜ν•œλ‹€.
      • λ§Œμ•½ now_gas>befor_gas라면, μ‹œμ•½μ„ 더 넣어도 더 λ§Žμ€ κ°€μŠ€κ°€ λ‚˜μ˜¬ κ²ƒμ΄λ―€λ‘œ now_gas==befor-gass인 상황이 μ˜€μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ break둜 λΉ μ Έλ‚˜μ˜¨λ‹€.
      • falseλ₯Ό λ°˜ν™˜ν•œλ‹€.

πŸ”Έ end πŸ”Έ

  • μš©μ•‘μ˜ 양을 μ–΄λ–»κ²Œ μ‘°μ ˆν•΄μ•Ό ν•˜λ‚˜ κ³ λ―Όν•˜λ‹€κ°€, λͺ¨λ“  경우λ₯Ό λ‹€ λ”°μ Έμ•Ό ν•  것 κ°™μ•„μ„œ μž¬κ·€ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν–ˆλ‹€.
  • μž¬κ·€ λ©”μ„œλ“œμ˜ 반볡 횟수 μ΅œμ ν™”λ₯Ό μœ„ν•΄ for문의 μ’…λ£Œ 쑰건을 μ§€μ •ν•˜λŠ”κ²Œ μ–΄λ €μ› λ˜ 것 κ°™λ‹€.
  • 문제 뢄석과 풀이 κ³„νšμ„ 적어가며 ν’€μ΄ν–ˆλ‹€.

728x90