2011-06-01 22:00:05Morris
d624. 燈泡問題
http://zerojudge.tw/ShowProblem?problemid=d624
內容 :
跨年夜你去了正妹小璇的家跨年(注意:只有跨年)
為了增加一點浪漫情調
你想讓燈泡開開關關的,以為這樣感覺會很有feel
但是燈泡連續暗太久小璇會感到害怕並且從此不理你
小璇能忍受燈泡連續n單位的時間是暗的,而總時間是m單位時間。
你想寫一個程式,給定n和m的值,算出有幾種不同的明暗排列方式,每一種排列方式之中都不會出現暗超過連續 n單位時間的區段。
輸入說明
:
有兩個數字n和m以一個空白分開,其中 1<=n<=15,1<=m<=90。
輸出說明
:
對於每一筆輸入請輸出一個數字,代表排列方式的總數。每個答案保證不會超過264-1,所以你不必考
慮有大數的情況會發生。
範例輸入 :
2 4
範例輸出 :
13
提示
:
範例輸出說明:
亮用○表示,暗用●表示,則有下面13種方式。
1 ○○○○ 2 ●○○○ 3 ●○●●
4 ●●○● 5 ○○○● 6 ○○●●
7 ○●○● 8 ○●●○ 9 ●○○●
10 ●○●○ 11 ●●○○ 12 ○○●○
13 ○●○○
以下是不合題目敘述的方式。
1 ●●●● 2 ○●●● 3 ●●●○
出處
:
TIOJ
(管理:david942j)
作法 : DP
我不會導公式,所以別 ... 請你提供
DP[m][n][p] m : 總共m個燈泡, n : 連續暗的最大剛好n個, p : 在結尾有連續 p 個是暗的
定義 :
[1][0][0] = 1, [1][1][1] = 1;
1 . n = 0, p =0 : DP[m][0][0] = 1; (基本的)
2. p = 0 : DP[m][n][0] = DP[m-1][n][0~n] (在結尾補亮的)
3. n = p : DP[m][n][n] = DP[m-1][0~m][n-1](在結尾補暗的)
4. p = 1 : DP[m][n][1] = DP[m-1][n][0](在結尾補暗的)
5. others : DP[m][n][p] = DP[m-1][n][p-1](在結尾補暗的)
Ans = DP[m][0~n][0~n]
/**********************************************************************************/
/* Problem: d624 "燈泡問題" from TIOJ */
/* Language: C */
/* Result: AC (4ms, 1306KB) on ZeroJudge */
/* Author: morris1028 at 2011-06-01 21:39:50 */
/**********************************************************************************/
#include<stdio.h>
main() {
int n, m, p, a, b;
long long DP[91][91][16] = {};
DP[1][0][0] = 1, DP[1][1][1] = 1;
for(m = 2; m <= 90; m++)
for(n = 0; n <= m; n++)
for(p = 0; p <= 15 && p <= n; p++) {
if(n == 0 && p == 0)
DP[m][0][0] = 1;
else if(p == 0) {
for(a = 0; a <= n && a <= 15; a++)
DP[m][n][0] += DP[m-1][n][a];
}
else if(n == p) {
for(a = 0; a <= n; a++)
DP[m][n][n] += DP[m-1][a][n-1];
}
else if(p == 1)
DP[m][n][1] = DP[m-1][n][0];
else
DP[m][n][p] = DP[m-1][n][p-1];
}
while(scanf("%d %d", &n, &m) == 2) {
long long Ans = 0;
for(a = 0; a <= n; a++)
for(b = 0; b <= n; b++)
Ans += DP[m][a][b];
printf("%lld\n", Ans);
}
return 0;
}
作法 : DP
我不會導公式,所以別 ... 請你提供
DP[m][n][p] m : 總共m個燈泡, n : 連續暗的最大剛好n個, p : 在結尾有連續 p 個是暗的
定義 :
[1][0][0] = 1, [1][1][1] = 1;
1 . n = 0, p =0 : DP[m][0][0] = 1; (基本的)
2. p = 0 : DP[m][n][0] = DP[m-1][n][0~n] (在結尾補亮的)
3. n = p : DP[m][n][n] = DP[m-1][0~m][n-1](在結尾補暗的)
4. p = 1 : DP[m][n][1] = DP[m-1][n][0](在結尾補暗的)
5. others : DP[m][n][p] = DP[m-1][n][p-1](在結尾補暗的)
Ans = DP[m][0~n][0~n]
/**********************************************************************************/
/* Problem: d624 "燈泡問題" from TIOJ */
/* Language: C */
/* Result: AC (4ms, 1306KB) on ZeroJudge */
/* Author: morris1028 at 2011-06-01 21:39:50 */
/**********************************************************************************/
#include<stdio.h>
main() {
int n, m, p, a, b;
long long DP[91][91][16] = {};
DP[1][0][0] = 1, DP[1][1][1] = 1;
for(m = 2; m <= 90; m++)
for(n = 0; n <= m; n++)
for(p = 0; p <= 15 && p <= n; p++) {
if(n == 0 && p == 0)
DP[m][0][0] = 1;
else if(p == 0) {
for(a = 0; a <= n && a <= 15; a++)
DP[m][n][0] += DP[m-1][n][a];
}
else if(n == p) {
for(a = 0; a <= n; a++)
DP[m][n][n] += DP[m-1][a][n-1];
}
else if(p == 1)
DP[m][n][1] = DP[m-1][n][0];
else
DP[m][n][p] = DP[m-1][n][p-1];
}
while(scanf("%d %d", &n, &m) == 2) {
long long Ans = 0;
for(a = 0; a <= n; a++)
for(b = 0; b <= n; b++)
Ans += DP[m][a][b];
printf("%lld\n", Ans);
}
return 0;
}