Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

45-9kyo-hwang #166

Merged
merged 5 commits into from
May 27, 2024
Merged

45-9kyo-hwang #166

merged 5 commits into from
May 27, 2024

Conversation

9kyo-hwang
Copy link
Collaborator

@9kyo-hwang 9kyo-hwang commented May 9, 2024

πŸ”— 문제 링크

2240 μžλ‘λ‚˜λ¬΄

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

1μ‹œκ°„ 반?

✨ μˆ˜λ„ μ½”λ“œ

1. 문제

μžλ‘ λ‚˜λ¬΄ 두 그루가 1번 μœ„μΉ˜μ™€ 2번 μœ„μΉ˜μ— μžˆλ‹€. 1μ΄ˆλΆ€ν„° $T$($1 \le T \le 1,000$)μ΄ˆκΉŒμ§€ 맀 μ΄ˆλ§ˆλ‹€ 두 λ‚˜λ¬΄ 쀑 ν•˜λ‚˜μ—μ„œ μžλ‘κ°€ 떨어진닀.
1번 μœ„μΉ˜μ—μ„œ μ‹œμž‘ν•΄μ„œ, μ΅œλŒ€ $W$($1 \le W \le 30$)번 움직여 μ΅œλŒ€ν•œ 많이 μžλ‘λ₯Ό μ–»κ³ μž ν•œλ‹€.
1번 μœ„μΉ˜μ™€ 2번 μœ„μΉ˜λ₯Ό μ΄λ™ν•˜λŠ” λ°λŠ” λ³„λ„μ˜ μ‹œκ°„μ΄ 듀지 μ•ŠλŠ”λ‹€κ³  ν•  λ•Œ, 얻을 수 μžˆλŠ” μ΅œλŒ€ μžλ‘ 개수λ₯Ό ꡬ해 좜λ ₯ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λΌ.

예λ₯Ό λ“€μ–΄ T = 7, W = 2 이고 μžλ‘κ°€ λ–¨μ–΄μ§€λŠ” λ‚˜λ¬΄ 정보가 [2, 1, 1, 2, 2, 1, 1] μ΄λ ‡κ²Œ μ£Όμ–΄μ‘Œμ„ λ•Œ

  • 1번 μœ„μΉ˜μ—μ„œ μ‹œμž‘ν•œλ‹€.
  • 1μ΄ˆμ— 2번 λ‚˜λ¬΄μ—μ„œ μžλ‘κ°€ 떨어진닀. ν•˜μ§€λ§Œ 움직이지 μ•Šμ•„ μžλ‘λ₯Ό 얻지 μ•ŠλŠ”λ‹€. -> 0
  • 2μ΄ˆμ— 1번 λ‚˜λ¬΄μ—μ„œ μžλ‘κ°€ 떨어진닀. μ—¬μ „νžˆ 1번 μœ„μΉ˜μ΄λ―€λ‘œ μžλ‘λ₯Ό ν•˜λ‚˜ μ–»λŠ”λ‹€. -> 1
  • 3μ΄ˆμ— 1번 λ‚˜λ¬΄μ—μ„œ μžλ‘κ°€ 떨어진닀. μ—¬μ „νžˆ 1번 μœ„μΉ˜μ΄λ―€λ‘œ μžλ‘λ₯Ό ν•˜λ‚˜ μ–»λŠ”λ‹€. -> 2
  • 4μ΄ˆμ— 2번 λ‚˜λ¬΄μ—μ„œ μžλ‘κ°€ 떨어진닀. 2번 μœ„μΉ˜λ‘œ 이동해 μžλ‘λ₯Ό ν•˜λ‚˜ μ–»λŠ”λ‹€. -> 3
  • 5μ΄ˆμ— 2번 λ‚˜λ¬΄μ—μ„œ μžλ‘κ°€ 떨어진닀. μ—¬μ „νžˆ 2번 μœ„μΉ˜μ΄λ―€λ‘œ μžλ‘λ₯Ό ν•˜λ‚˜ μ–»λŠ”λ‹€. -> 4
  • 6μ΄ˆμ— 1번 λ‚˜λ¬΄μ—μ„œ μžλ‘κ°€ 떨어진닀. 1번 μœ„μΉ˜λ‘œ 이동해 μžλ‘λ₯Ό ν•˜λ‚˜ μ–»λŠ”λ‹€. -> 5
  • 7μ΄ˆμ— 1번 λ‚˜λ¬΄μ—μ„œ μžλ‘κ°€ 떨어진닀. μ—¬μ „νžˆ 1번 μœ„μΉ˜μ΄λ―€λ‘œ μžλ‘λ₯Ό ν•˜λ‚˜ μ–»λŠ”λ‹€. -> 6

이 κ²½μš°κ°€ W번 이내 움직이며 μžλ‘λ₯Ό 6개둜 μ΅œλŒ€ν•œμœΌλ‘œ 얻을 수 μžˆλ‹€.

2. μž‘λ‹΄

디코에 μΆ”μ²œ 문제둜 올라온 μ§€λŠ” κ½€ λμœΌλ‚˜, 계속 μ•ˆ ν’€κ³  μžˆλ‹€κ°€ 이번 ν”„κ²½λŒ€ 3번 λ¬Έμ œμ—μ„œ 철퇴λ₯Ό λ‹Ήν•˜κ³  참회의 의미둜 ν’€κ²Œ λ˜μ—ˆλ‹€ 흑흑
μ§„μ§œ λ¬Έμ œκ°€ 거의 λΉ„μŠ·ν•˜λ„€...

3. 풀이

λ‹¨μˆœνžˆ μƒκ°ν•˜λ©΄

  • 0번 움직일 λ•Œ 얻을 수 μžˆλŠ” μ΅œλŒ€ μžλ‘ 개수
  • 1번 움직일 λ•Œ 얻을 수 μžˆλŠ” μ΅œλŒ€ μžλ‘ 개수
  • ...

이런 μ‹μœΌλ‘œ λͺ¨λ“  경우λ₯Ό λ‹€ λŒμ•„λ³΄λ©΄ ν’€ 수 μžˆλ‹€.

λ¬Έμ œλŠ” 1번 이상 움직일 수 있게 되면 "μ–΄λ””μ„œ 움직여야 μ΅œλŒ€μΈκ°€"λ₯Ό μ°ΎκΈ° μœ„ν•΄ 무수히 λ§Žμ€ 경우의 수λ₯Ό νŒŒμ•…ν•΄μ•Ό ν•œλ‹€.

그런데 잘 생각해보면 κ½€ λ§Žμ€ 경우의 μˆ˜κ°€ "쀑볡"λœλ‹€. 예λ₯Ό λ“€μ–΄ "2초 μ‹œμ μ— 1번 μœ„μΉ˜μ—μ„œ 2번 μœ„μΉ˜λ‘œ 이동"ν•œ κ²°κ³Όκ°€ λͺ¨λ“  κ²½μš°μ—μ„œ 단 ν•œ 번만 λ“±μž₯ν•˜μ§€ μ•ŠλŠ”λ‹€. 전역에 걸쳐 μ—¬λŸ¬ 번 ν™•μΈν•˜κ²Œ 될 것이닀.

κ·Έλ ‡λ‹€λ©΄, "λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°" κ°œλ…μ„ μ μš©μ‹œμΌœ κ²°κ³Όλ₯Ό μΊμ‹±ν•΄λ†“μœΌλ©΄ 쀑볡을 쀄일 수 μžˆλ‹€.

쑰금 더 μƒκ°ν•΄λ³΄μž.
제λͺ©μ„ μž…λ ₯ν•΄μ£Όμ„Έμš”_-001 (7)

상황을 μΌλ°˜ν™”ν•΄λ³΄λ©΄, T - 1초 μ‹œμ μ—μ„œ 1번/2번 μœ„μΉ˜μ—μ„œ 이동을 ν•˜λ˜κ°€ μ•ˆν•˜λ˜κ°€ ν•΄μ„œ T초 μ‹œμ μ— 각각 μ΅œλŒ€λ‘œ 많이 λ”΄ μžλ‘ 개수λ₯Ό 기둝할 수 μžˆλ‹€.
이 κ³Όμ •μ—μ„œ λ§Œμ•½ ν•œ λ²ˆλ„ μ•ˆμ›€μ§μ΄λŠ” 경우라면 a -> c, b -> d만 ν—ˆμš©λ  것이고, μ•„λ‹ˆλΌλ©΄ 두 경우 λͺ¨λ‘ κ³ λ €ν•˜κ²Œ 될 것이닀. 즉 움직일 수 μžˆλŠ” νšŸμˆ˜μ— 따라 경우의 μˆ˜κ°€ λ‚˜λ‰œλ‹€.

즉 1. μ‹œκ°„ 정보 2. μ’Œν‘œ 정보 3. 움직인 횟수 정보 3가지λ₯Ό 가지고 ν…Œμ΄λΈ”μ„ λ§Œλ“€λ©΄ μΌλ°˜ν™”λœ 점화식을 μ΄μš©ν•΄ bottom-up λ°©μ‹μ˜ dpλ₯Ό κ΅¬ν˜„ν•  수 있게 λœλ‹€. 이제 μ½”λ“œλ‘œ ν™•μΈν•΄λ³΄μž.

T, W = map(int, input().split())
poses = [int(input()) for _ in range(T)]
poses = [0] + [pos - 1 for pos in poses]

주어진 μž…λ ₯을 μ €μž₯ν•œλ‹€. 인덱슀 처리λ₯Ό νŽΈλ¦¬ν•˜κ²Œ ν•˜κΈ° μœ„ν•΄μ„œ 1번, 2λ²ˆμ„ 0번, 1번으둜 λ°”κΏ”μ„œ μ €μž₯ν•œλ‹€.
λ˜ν•œ μ‹œμž‘ μœ„μΉ˜κ°€ 1λ²ˆμ΄λ―€λ‘œ μ’Œν‘œ 리슀트 맨 μ•žμ— [0]을 덧뢙인닀.

dp[w][t][0] = max(dp[w][t - 1][0], dp[w - 1][t - 1][1]) + (poses[t] == 0)
dp[w][t][1] = max(dp[w - 1][t - 1][0], dp[w][t - 1][1]) + (poses[t] == 1)

μœ„ 그림을 ν† λŒ€λ‘œ μΌλ°˜ν™”λœ 점화식을 μ„Έμš°λ©΄ μœ„μ™€ κ°™λ‹€.
dp[w][t][0]λŠ” w번 움직인 μƒν™©μ—μ„œ, t초 μ‹œμ μ— 0번 μœ„μΉ˜μ—μ„œ 얻을 수 μžˆλŠ” μ΅œλŒ€ μžλ‘ 개수λ₯Ό μ˜λ―Έν•œλ‹€. μ΄λŠ”

  • t-1초 μ‹œμ μ— 0번 μœ„μΉ˜μ—μ„œ 움직이지 μ•Šκ³ (w) κ°€λ§Œνžˆ 있던 경우
  • t-1초 μ‹œμ μ— 1번 μœ„μΉ˜μ—μ„œ μ›€μ§μ—¬μ„œ(w-1) 0번 μ§€μ μœΌλ‘œ 온 경우

μœ„ 두 경우 쀑 큰 κ²½μš°μ—, t초 μ‹œμ μ— μžλ‘κ°€ λ–¨μ–΄μ§€λŠ” λ‚˜λ¬΄ μœ„μΉ˜κ°€ 0이면(poses[t] == 0) + 1을 ν•œ κ²½μš°κ°€ μ΅œλŒ€μ΄λ‹€.
dp[w][t][1]도 λ™μΌν•œ 논리이닀.

μ—¬κΈ°μ„œ μ˜ˆμ™Έλ‘œ μ²˜λ¦¬ν•΄μ•Ό ν•  κ²½μš°κ°€ 2가지 μžˆλŠ”λ°

  1. 움직일 수 μžˆλŠ” νšŸμˆ˜κ°€ 0이라면 계속 0번 μœ„μΉ˜μ— μžˆλ˜κ°€ 1번 μœ„μΉ˜μ— μžˆμ–΄μ•Ό ν•œλ‹€.
    제λͺ©μ„ μž…λ ₯ν•΄μ£Όμ„Έμš”_-001 (11)
if w == 0:
    dp[w][t][0] = dp[w][t - 1][0] + (poses[t] == 0)
    dp[w][t][1] = dp[w][t - 1][1] + (poses[t] == 1)
    continue

즉 t-1초 μ‹œμ μ— ν•΄λ‹Ή μœ„μΉ˜μ— κ°€λ§Œνžˆ 있던 경우만 ν™•μΈν•œλ‹€.

  1. μ‹œμž‘ μœ„μΉ˜λŠ” 0번으둜 κ³ μ •λΌμžˆκΈ° λ•Œλ¬Έμ—, 1초 μ‹œμ μ—μ„œλŠ” 1번 μœ„μΉ˜μ—μ„œ 온 경우λ₯Ό κ³ λ €ν•΄μ„œλŠ” μ•ˆλœλ‹€.
    제λͺ©μ„ μž…λ ₯ν•΄μ£Όμ„Έμš”_-001 (9)
dp[w][1][0] = dp[w][0][0] + (poses[1] == 0)
if w > 0:
    dp[w][1][1] = dp[w - 1][0][0] + (poses[1] == 1)

1초 μ‹œμ μ—, 0번 μœ„μΉ˜λŠ” 0번 μœ„μΉ˜ κ·ΈλŒ€λ‘œ κ°€μ Έμ˜€κ³ , 1번 μœ„μΉ˜λŠ” 0번 μœ„μΉ˜μ—μ„œ 1번 움직인 경우만 ν™•μΈν•œλ‹€.

이λ₯Ό 0번 움직일 수 μžˆλŠ” 경우 ~ W번 움직일 수 μžˆλŠ” 경우λ₯Ό λ‹€ λŒμ•„λ³΄λ©΄μ„œ 맀 초(1 ~ T) 값을 κ°±μ‹ ν•΄μ£Όλ©΄ λœλ‹€.

λ§ˆμ§€λ§‰μœΌλ‘œ, T초 μ‹œμ μ—μ„œ 0번, 1번, ..., W번 μ›€μ§μ˜€μ„ λ•Œ 0번/1번 μœ„μΉ˜μ— 기둝된 μ΅œλŒ€ μžλ‘ 개수λ₯Ό 좜λ ₯ν•˜λ©΄ 완성이닀.

print(max(max(dp[w][T][0], dp[w][T][1]) for w in range(W + 1)))

전체 μ½”λ“œ

input = open(0).readline

T, W = map(int, input().split())
poses = [int(input()) for _ in range(T)]
poses = [0] + [pos - 1 for pos in poses]

dp = [[[0] * 2 for _ in range(T + 1)] for _ in range(W + 1)]

for w in range(W + 1):
    dp[w][1][0] = dp[w][0][0] + (poses[1] == 0)
    if w > 0:
        dp[w][1][1] = dp[w - 1][0][0] + (poses[1] == 1)
    
    for t in range(2, T + 1):
        if w == 0:
            dp[w][t][0] = dp[w][t - 1][0] + (poses[t] == 0)
            dp[w][t][1] = dp[w][t - 1][1] + (poses[t] == 1)
            continue
        
        dp[w][t][0] = max(dp[w][t - 1][0], dp[w - 1][t - 1][1]) + (poses[t] == 0)
        dp[w][t][1] = max(dp[w - 1][t - 1][0], dp[w][t - 1][1]) + (poses[t] == 1)
        

print(max(max(dp[w][T][0], dp[w][T][1]) for w in range(W + 1)))
  • c++
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    
    int T, W; cin >> T >> W;
    vector<int> Poses(T + 1, 0);
    for(int t = 1; t <= T; ++t)
    {
        cin >> Poses[t];
        Poses[t] -= 1;
    }
    
    vector<vector<vector<int>>> DP(W + 1, vector(T + 1, vector(2, 0)));
    
    for(int Walk = 0; Walk <= W; ++Walk)
    {
        DP[Walk][1][0] = DP[Walk][0][0] + (Poses[1] == 0);
        if(Walk > 0)
        {
            DP[Walk][1][1] = DP[Walk - 1][0][0] + (Poses[1] == 1);
        }
        
        for(int Time = 2; Time <= T; ++Time)
        {
            if(Walk == 0)
            {
                DP[Walk][Time][0] = DP[Walk][Time - 1][0] + (Poses[Time] == 0);
                DP[Walk][Time][1] = DP[Walk][Time - 1][1] + (Poses[Time] == 1);
                continue;
            }
            
            DP[Walk][Time][0] = max(DP[Walk][Time - 1][0], DP[Walk - 1][Time - 1][1]) + (Poses[Time] == 0);
            DP[Walk][Time][1] = max(DP[Walk - 1][Time - 1][0], DP[Walk][Time - 1][1]) + (Poses[Time] == 1);
        }
    }
    
    int Ans = 0;
    for(int Walk = 0; Walk <= W; ++Walk)
    {
        Ans = max({Ans, DP[Walk][T][0], DP[Walk][T][1]});
    }
    cout << Ans;
    
    return 0;
}

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

μ—μž‰ μ΄μƒν•œ μ‚½μ§ˆν•œλ‹€κ³  μ‹œκ°„ λ„ˆλ¬΄ 많이 λ‚ λ Έλ‹€.

μ—νœ΄ μ§„μž‘μ— ν’€μ–΄λ³Όκ±Έ...

Copy link
Member

@xxubin04 xxubin04 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dp[w][t][0] = max(dp[w][t - 1][0], dp[w - 1][t - 1][1]) + (poses[t] == 0)
dp[w][t][1] = max(dp[w - 1][t - 1][0], dp[w][t - 1][1]) + (poses[t] == 1)

μ΄λ ‡κ²Œ poses[t] == 0, 1둜 κ΅¬ν˜„ν•œκ²Œ μ—„μ²­ μ°Έμ‹ ν•œκ±Έμš”?!
DPλŠ” 아직 μ–΄λ €μ›Œμ„œ PR λ³΄λ©΄μ„œ μ‰½κ²Œ 이해할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€!
λΈ”λ‘œκ·Έλ„ μ°Έκ³ ν•΄μ„œ λ³΄λ‹ˆ λͺ‡ 번째 λ‚˜λ¬΄μΈμ§€(T)둜 μ‹œμž‘ν•˜μ—¬ λͺ‡ 번 λ°”κΏ¨λŠ”μ§€(W)둜 μ§„ν–‰ν•˜λŠ” 방법도 μžˆλ”λΌκ΅¬μš”.
참고해도 쒋을 것 κ°™μ•„ μ‚¬μ§„μœΌλ‘œλ§Œ λ‚¨κ²¨λ΄…λ‹ˆλ‹€..😊

λΈ”λ‘œκ·Έ μ°Έκ³ 

image

Copy link
Member

@gjsk132 gjsk132 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2차원 DP둜 ν’€μ—ˆμŠ΅λ‹ˆλ‹€!

dp[μ‹œκ°„][자리λ₯Ό λ°”κΎΌ 횟수]둜 μ•Œλ©΄ 될 것 κ°™μŠ΅λ‹ˆλ‹€.

2μ°¨μ›μœΌλ‘œ 쀄일 수 μžˆμ—ˆλ˜ μ΄μœ λŠ” 자리λ₯Ό 바꿨을 λ•Œ, 얻을 수 μžˆλŠ” μžλ‘λ‚˜λ¬΄μ˜ λ²ˆν˜ΈλŠ” μ •ν•΄μ Έ μžˆλ‹€λŠ” 것을 μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄
자리λ₯Ό 1번 λ°”κΎΈλ©΄, 2번 μžλ‘λ‚˜λ¬΄ / 자리λ₯Ό 2번 λ°”κΎΈλ©΄, 1번 μžλ‘λ‚˜λ¬΄
ν™€μˆ˜λ§ŒνΌ λ°”κΎΈλ©΄ 2λ²ˆμ„ 먹을 수 있고, 짝수만큼 λ°”κΎΈλ©΄ 1λ²ˆμ„ 먹을 수 μžˆμŠ΅λ‹ˆλ‹€.

κ²°κ΅­ μ–΄λ–€ μ‹œκ°„μ— μžλ‘λ₯Ό 먹을 수 μžˆλƒ 없냐λ₯Ό μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄μ œλΆ€ν„΄ DPμœ ν˜•μ—μ„œ 많이 ν•΄λ³Έ λŠλ‚Œμ΄λΌμ„œ 더 κ°„λ‹¨ν•©λ‹ˆλ‹€.
μ΄μ „μ˜ μ‹œκ°„μ—μ„œ 자리λ₯Ό λ°”κΏ€ λ•Œμ™€ κ·ΈλŒ€λ‘œ 왔을 λ•Œ μ€‘μ—μ„œ 더 큰 값을 더해주면 λ©λ‹ˆλ‹€.

μœ„ 과정을 μ΄μš©ν•΄μ„œ κ²°κ³Όλ₯Ό λ‚΄λ©΄ μ•„λž˜ 이미지와 같은 κ²°κ³Όκ°€ λ‚˜μ˜΅λ‹ˆλ‹€.

그럼 제일 λ§ˆμ§€λ§‰ μ‹œκ°„μ—μ„œ max 값을 μ°Ύμ•„μ„œ 좜λ ₯ν•˜λ©΄ λ©λ‹ˆλ‹€.

input = open("input.txt").readline

time, can_change = map(int,input().split())

dp = [[0]*(can_change+1) for _ in range(time)]

for t in range(time):
    for set in range(int(input())-1, can_change+1, 2):
        dp[t][set] += 1

for t in range(1, time):
    for idx in range(min(t, can_change)+1):
        if idx == 0:
           dp[t][idx] += dp[t-1][idx]
           continue

        dp[t][idx] += max(dp[t-1][idx-1], dp[t-1][idx])

print(max(dp[-1]))

λ°”λ‘œ μ΄μ „μ˜ κ°’λ§Œ κΈ°μ–΅ν•˜λ©΄ 되기 λ•Œλ¬Έμ—, timeλ§ˆλ‹€ κΈ°μ–΅ν•˜μ§€ μ•Šμ•„λ„ λ˜λŠ” 점을 μ΄μš©ν•˜λ©΄ λ©”λͺ¨λ¦¬λ₯Ό 더 쀄일 수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€.πŸ€”

@gjsk132
Copy link
Member

gjsk132 commented May 26, 2024

  1. μ‹œκ°„ 정보 2. μ’Œν‘œ 정보 3. 움직인 횟수 정보 3가지

κ°„λ‹¨ν•˜κ²Œ λ§ν•˜λ©΄, 2번 정보λ₯Ό μƒλž΅ν•œ 방법인 것 κ°™μŠ΅λ‹ˆλ‹€!

@9kyo-hwang 9kyo-hwang merged commit 53e6bc8 into main May 27, 2024
7 checks passed
@9kyo-hwang 9kyo-hwang deleted the 45-9kyo-hwang branch May 27, 2024 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants