From 98303616c9b93b51465472adc15854fbad4abb8d Mon Sep 17 00:00:00 2001 From: "phluenam@gmail.com" Date: Mon, 9 Oct 2023 05:47:38 +0800 Subject: [PATCH 1/2] add 1079 --- md/1079.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 md/1079.md diff --git a/md/1079.md b/md/1079.md new file mode 100644 index 0000000..649692d --- /dev/null +++ b/md/1079.md @@ -0,0 +1,27 @@ +ข้อนี้ต้องถามว่าหากต้องแบ่งหุงข้าว $N$ จาน โดยแต่ละครั้งหุงได้เกิน $K$ จานต่อครั้ง จะสามารถแบ่งหุงจนครบ $N$ ได้กี่วิธี + +สำหรับข้อนี้วิธีแรกที่เห็นได้ง่ายที่สุดคือ Dynamic Programming โดยเห็นได้ว่า $dp[i] = \Sigma_{j=max(0,i-k)}^i dp[j]$ (ในการหุงครั้งจากต้องการ $i$ จะเหลือต้องการ $j$ จานโดย $i-k\leq j\leq i-1$) + +แต่เนื่องจากข้อนี้กำหนด $N \leq 100000, K \leq 100000$ วิธีนี้ที่ใช้เวลา $\mathcal{O}(NK)$ จึงช้าเกินไป เราจึงต้องใช้วิธีที่เร็วกว่านี้ + +เราสามารถกำหนด $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(1)$ ($C[i]$ สามารถคำนวณเป็น $C[i]=C[i-1] + dp[i]$ ในเวลา $\mathcal{O}(1)$ เช่นกัน) + +ดังนั้นจึงต้องใช้เวลาเพียง $O(1)$ สำหรับการคำนวณ $C[i]$ และ $dp[i]$ สำหรับแต่ละ $i \leq N$ ทั้งหมดจึงใช้เวลา $\mathcal{O}(N)$ + +โค้ดประกอบคำอธิบาย + +```cpp + dp[0] = 1; + C[0] = 1; + for(int i=1;i<=n;i++) + { + if (i-k-1>=0) + dp[i] = C[i-1] - C[i-k-1]; + else + dp[i] = C[i-1]; + dp[i] = dp[i] %2009; + if(dp[i]<0) + dp[i]+=2009; + C[i] = C[i-1] + dp[i] %2009; + } +``` \ No newline at end of file From 2c734d6a8b67de96a5faf94a59c828f834a8e6f9 Mon Sep 17 00:00:00 2001 From: "phluenam@gmail.com" Date: Mon, 9 Oct 2023 05:48:51 +0800 Subject: [PATCH 2/2] edit --- md/1079.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/md/1079.md b/md/1079.md index 649692d..98def65 100644 --- a/md/1079.md +++ b/md/1079.md @@ -1,12 +1,12 @@ ข้อนี้ต้องถามว่าหากต้องแบ่งหุงข้าว $N$ จาน โดยแต่ละครั้งหุงได้เกิน $K$ จานต่อครั้ง จะสามารถแบ่งหุงจนครบ $N$ ได้กี่วิธี -สำหรับข้อนี้วิธีแรกที่เห็นได้ง่ายที่สุดคือ Dynamic Programming โดยเห็นได้ว่า $dp[i] = \Sigma_{j=max(0,i-k)}^i dp[j]$ (ในการหุงครั้งจากต้องการ $i$ จะเหลือต้องการ $j$ จานโดย $i-k\leq j\leq i-1$) +สำหรับข้อนี้วิธีแรกที่เห็นได้ง่ายที่สุดคือ Dynamic Programming โดยเห็นได้ว่า $dp[i] = \Sigma_{j=\max(0,i-k)}^i dp[j]$ (ในการหุงครั้งจากต้องการ $i$ จะเหลือต้องการ $j$ จานโดย $i-k\leq j\leq i-1$) แต่เนื่องจากข้อนี้กำหนด $N \leq 100000, K \leq 100000$ วิธีนี้ที่ใช้เวลา $\mathcal{O}(NK)$ จึงช้าเกินไป เราจึงต้องใช้วิธีที่เร็วกว่านี้ -เราสามารถกำหนด $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(1)$ ($C[i]$ สามารถคำนวณเป็น $C[i]=C[i-1] + dp[i]$ ในเวลา $\mathcal{O}(1)$ เช่นกัน) +เราสามารถกำหนด $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)$ เช่นกัน) -ดังนั้นจึงต้องใช้เวลาเพียง $O(1)$ สำหรับการคำนวณ $C[i]$ และ $dp[i]$ สำหรับแต่ละ $i \leq N$ ทั้งหมดจึงใช้เวลา $\mathcal{O}(N)$ +ดังนั้นจึงต้องใช้เวลาเพียง $\mathcal{O}(1)$ สำหรับการคำนวณ $C[i]$ และ $dp[i]$ สำหรับแต่ละ $i \leq N$ ทั้งหมดจึงใช้เวลา $\mathcal{O}(N)$ โค้ดประกอบคำอธิบาย