核電站問題轉載自saltless原創

Rqnoj105 核電站問題 題解

      又回到我可愛的Blog了~昨天偷了點懶,一篇文章也沒寫~今天一定抽時間補上。

      下面切入正題。

 

 

【題目描述】(rqnoj105)
一個核電站有N個放核物質的坑,坑排列在一條直線上。如果連續M個坑中放入核物質,則會發生爆炸,於是,在某些坑中可能不放核物質。
任務:對於給定的N和M,求不發生爆炸的放置核物質的方案總數
 
【輸入格式】
輸入文件只一行,兩個正整數N,M( 1<N<50,2≤M≤5)
 
【輸出格式】
輸出文件只有一個正整數S,表示方案總數。
 
【樣例輸入】
4 3
 
【樣例輸出】
13

 

 

      這是一道線性遞推類的動態規劃。說實話,這道題我直接看的題解,竟然沒有看懂,糾結我一節課…先把代碼貼上:

 

 

複製代碼
1 program nuclear; 2 var 3 f:array[-6..60]of int64; 4 i,m,n:integer; 5 begin 6 readln(n,m); 7 f[0]:=1; 8 f[-1]:=1; 9 for i:=1 to n do 10 f[i]:=2*f[i-1]-f[i-m-1]; 11 writeln(f[n]); 12 end.  
複製代碼

 

 

      這巨短的代碼理解起來還真不容易。首先,f數組存儲的是到第f個坑可能出現的情況數。網上很多題解都用到分情況討論,根據Jingo大牛的無敵思想,只要把數組向前多定m位,即-m到n即可。

      另外一個比較糾結的地方就是這個神奇的動態方程。你可以自己分析一下,如果不懂請看下文。

      我們先將方程分解,即f[i]:=f[i-1]+f[i-1]-f[i-m-1],這是顯而易見的。兩個f[i-1]分別代表的是f[i]位上放或者不放。但是f[i]上能放的條件是連續的一排上最多有m-1堆。以樣例爲例,當i=4時有以下狀態:

 

 

 

 

 

      因爲如果在(4)放,在(3)號坑放的前提下(2)一定是不放的。所以要用在f[i-1](3號坑放的那一個)中排除有(2)且有(3)的那種情況。

      由題意可知,如果(2)(3)都有核物質,(1)中一定沒有。所以能達到圖中的的狀態的情況數只等於f[0],即f[i-m-1]的值。這時f[i-1]-f[i-m-1]就好理解了。

      還有一個問題就是爲什麼f[0]和f[-1]都初始化爲1。這可以從上文很簡單的找到答案。因爲當i=m(i-m-1=-1)或i=m+1(i-m-1=0)時,需要減去i,i-1,…,i-m+1都有核物質的這一種不符合題意的情況。

      現在請把鼠標滾輪向上滾,重新看一遍代碼。這是你就可以體會到這段偉大的O(n)的DP代碼的魅力了。

 

(saltless原創,轉載請註明出處)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章