Skip to content

Commit 89df598

Browse files
authored
Merge pull request #147 from Phluenam/add_1079
Add 1079
2 parents 142d142 + d4a1390 commit 89df598

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

md/1079.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
ข้อนี้ต้องถามว่าหากต้องแบ่งหุงข้าว $N$ จาน โดยแต่ละครั้งหุงได้เกิน $K$ จานต่อครั้ง จะสามารถแบ่งหุงจนครบ $N$ ได้กี่วิธี
2+
3+
สำหรับข้อนี้วิธีแรกที่เห็นได้ง่ายที่สุดคือ Dynamic Programming โดยเห็นได้ว่า $dp[i] = \Sigma_{j=\max(0,i-k)}^i dp[j]$ (ในการหุงครั้งจากต้องการ $i$ จะเหลือต้องการ $j$ จานโดย $i-k\leq j\leq i-1$)
4+
5+
แต่เนื่องจากข้อนี้กำหนด $N \leq 100000, K \leq 100000$ วิธีนี้ที่ใช้เวลา $\mathcal{O}(NK)$ จึงช้าเกินไป เราจึงต้องใช้วิธีที่เร็วกว่านี้
6+
7+
เราสามารถกำหนด $C[i] = \Sigma_{j=0}^i dp[j]$ ซึ่งจะทำให้สามารถคำนวณ $dp[i] = C[i-1]$ เมื่อ $i-k-1 < 0$ และ $dp[i] = C[i-1] - C[i-k-1]$ เมื่อ $i-k-1 \geq 0$ ในเวลา $\mathcal{O}(1)$ ($C[i]$ สามารถคำนวณเป็น $C[i]=C[i-1] + dp[i]$ ในเวลา $\mathcal{O}(1)$ เช่นกัน)
8+
9+
ดังนั้นจึงต้องใช้เวลาเพียง $\mathcal{O}(1)$ สำหรับการคำนวณ $C[i]$ และ $dp[i]$ สำหรับแต่ละ $i \leq N$ ทั้งหมดจึงใช้เวลา $\mathcal{O}(N)$
10+
11+
โค้ดประกอบคำอธิบาย
12+
13+
```cpp
14+
dp[0] = 1;
15+
C[0] = 1;
16+
for(int i=1;i<=n;i++)
17+
{
18+
if (i-k-1>=0)
19+
dp[i] = C[i-1] - C[i-k-1];
20+
else
21+
dp[i] = C[i-1];
22+
dp[i] = dp[i] %2009;
23+
if(dp[i]<0)
24+
dp[i]+=2009;
25+
C[i] = C[i-1] + dp[i] %2009;
26+
}
27+
```

0 commit comments

Comments
 (0)