799. Champagne Tower

  • λ¬Έμ œμ—μ„œ μ„€λͺ…λœ λŒ€λ‘œ 첫번째 μž” λΆ€ν„° λΆ€μ–΄μ§„ μƒ΄νŽ˜μΈ 숫자λ₯Ό κΈ°μ€€μœΌλ‘œ λ„˜μΉœ 양을 κ³„μ‚°ν•΄μ„œ λ‹€μŒμž”μ˜ μƒ΄νŽ˜μΈ 양을 κ³„μ‚°ν•΄λ‚˜κ°€λ©΄ λœλ‹€.
    • 계산 μ•ˆν•˜κ³  ν•  수 μžˆλŠ” 방법이 μžˆλ‚˜ κ³ λ―Όν•΄λ΄€λŠ”λ° λ³„λ‘œ λ– μ˜€λ₯΄λŠ” 방법이 μ—†λŠ”κ²ƒ κ°™λ‹€.
  • query_row = R 이라고 ν•  λ•Œ ν•΄λ‹Ήλ˜λŠ” row의 μƒ΄νŽ˜μΈ μž”μ˜ μƒνƒœλ₯Ό κ³„μ‚°ν•˜λ €λ©΄ λ‹€μŒ rowκΉŒμ§€ μžˆμ–΄μ•Ό ν•˜λ―€λ‘œ 총 (R + 1) * (R + 2) / 2 개의 μž”μ΄ ν•„μš”ν•˜λ‹€.
    • R + 1 row의 μƒ΄νŽ˜μΈ 양은 섀사 λ„˜μ³€λ‹€κ³  ν•˜λ”λΌλ„ 쿼리 λŒ€μƒμ΄ μ•„λ‹ˆλ―€λ‘œ ꡳ이 계산할 ν•„μš”κ°€ μ—†λ‹€.
  • μ–΄λ–€ μž”μ˜ 와인 양을 G(r, c) 라고 ν•  λ•Œ
    • G(r, c) ≀ 1.0 인 κ²½μš°μ—λŠ” λ„˜μΉ˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ 아무 것도 ν•˜μ§€ μ•ŠλŠ”λ‹€.
    • G(r, c) > 1.0 인 κ²½μš°μ—λŠ” λ„˜μΉœ μ–‘ G(r, c) - 1.0 을 반으둜 λ‚˜λˆ„μ–΄ 각각 κ·Έ μ•„λž˜μ— μžˆλŠ” 두 μž” G(r + 1, c), G(r + 1, c + 1) 에 λΆ„λ°°ν•œλ‹€.
class Solution { public: double champagneTower(int poured, int query_row, int query_glass) { vector<double> glass((query_row + 2) * (query_row + 3) / 2); glass[0] += poured; int row_start = 0; for (int row = 0; row <= query_row; ++row) { bool found_excess = false; int next_row_start = row_start + row + 1; for (int col = 0; col <= row; ++col) { double excess = glass[row_start + col] - 1.0; if (excess <= 0.0) continue; found_excess = true; glass[next_row_start + col] += excess / 2.0; glass[next_row_start + col + 1] += excess / 2.0; glass[row_start + col] = 1.0; } if (!found_excess) break; row_start = next_row_start; } row_start = query_row * (query_row + 1) / 2; return glass[row_start + query_glass]; } };
  • λ©”λͺ¨λ¦¬ 곡간을 μ’€ 더 아끼고 μ‹Άλ‹€λ©΄ μ•„λž˜μ²˜λŸΌ rowλ₯Ό 2개 μ •μ˜ν•˜κ³  toggle ν•˜μ—¬ μ‚¬μš©ν•˜λŠ” 방법도 μžˆλ‹€.
class Solution { public: double champagneTower(int poured, int query_row, int query_glass) { vector<double> cur_row(query_row + 2); vector<double> next_row(query_row + 2); next_row[0] += poured; int last_row = 0; for (int row = 0; row <= query_row; ++row) { cur_row.swap(next_row); fill(next_row.begin(), next_row.begin() + row + 1, 0); bool found_excess = false; for (int col = 0; col <= row; ++col) { double excess = cur_row[col] - 1.0; if (excess <= 0.0) continue; found_excess = true; next_row[col] += excess / 2.0; next_row[col + 1] += excess / 2.0; cur_row[col] = 1.0; } last_row = row; if (!found_excess) break; } return last_row == query_row ? cur_row[query_glass] : 0.0; } };