2011-09-16 06:58:24Morris
d664. 11725 - Colorful Board
d664. 11725 - Colorful Board
內容 :
給你一個板子,在上面M條水平線跟N條垂直線,因此在整個板子有(M+1) x (N+1)格子,現在請你在每個格子上填上顏色,總共有4種顏色Red,Green,Blue,Orange。
為了使板子更加漂亮,你必須小心一件事情,兩鄰的格子不能有相同的顏色(相鄰的定義是有共同的邊),但是有些格子是被禁止塗上任何顏色的,題目來了,你必須回答有幾種方式可以塗完,但不觸犯以上規則。
輸入說明
:
第一個數字T(T<=50)代表有幾組冊資,每一組測資會給兩格數字M,N(0<M,N<=6)代表有幾條水平線跟垂直線,下一行但表有幾格被禁止不能圖畫的個數K(0<=K<=(M+1)*(N+1) ),接下來K行會包含兩個數字X,Y (1<=x<=M+1, 1<=y<=N+1),代表第X行的第Y個是被禁止塗畫。
輸出說明
:
對於每一個測資,請輸出一行 "Case #K: P",K代表第幾組測試資料,P代表有幾種可能,由於答案可能很大,請mod 1000000007
範例輸入 :
2 1 1 1 2 1 0 0 0
範例輸出 :
Case 1: 36 Case 2: 4
提示
:
出處
:
UVA 11725
(管理:snail)
作法 : DP
總共 5 種情況, 0 沒填 1~4 四種顏色, 每一行可以用一個五進制表示,
因此可以得到, 每一行的總狀態, 在依照相鄰不可同色, 進行狀態轉移,
作法 : DP
總共 5 種情況, 0 沒填 1~4 四種顏色, 每一行可以用一個五進制表示,
因此可以得到, 每一行的總狀態, 在依照相鄰不可同色, 進行狀態轉移,
/**********************************************************************************/
/* Problem: d664 "11725 - Colorful Board" from UVA 11725 */
/* Language: C (1695 Bytes) */
/* Result: AC(676ms, 1.2MB) judge by this@ZeroJudge */
/* Author: morris1028 at 2011-09-15 16:16:05 */
/**********************************************************************************/
#include<stdio.h>
#include<string.h>
void change(int n, char *s) {
if(n == 0) return;
change(n/5, s+1);
*s = n%5;
}
int Calu(int n, char *s) {
if(n == 0) return 0;
return Calu(n-1, s+1)*5+(*s);
}
main() {
int T, n, m, K, x, y, C = 1;
int map[8][8], s5[10] = {1};
int i, j, k, l;
for(i = 1; i < 10; i++)
s5[i] = s5[i-1]*5;
scanf("%d", &T);
while(T--) {
scanf("%d %d", &m, &n);
scanf("%d", &K);
memset(map, 0, sizeof(map));
for(i = 0; i < K; i++) {
scanf("%d %d", &x, &y);
map[x][y] = 1;
}
m++, n++;
int last[78126], now[78126];
int state = s5[n]-1, tmp, now_state;
char CH[10];
memset(last, 0, sizeof(last));
last[0] = 1;
for(i = 0; i < m; i++) {
for(j = 1; j <= n; j++) {
for(k = 0; k <= state; k++) {
memset(CH, 0, sizeof(CH));
change(k, CH);
if(last[k] == 0) continue;
if(j != 1 && CH[j-2] == 0 && map[i+1][j-1] == 0) continue;
if(j != 1 && CH[j-2] != 0 && map[i+1][j-1] != 0) continue;
if(map[i+1][j]) {
CH[j-1] = 0;
now_state = Calu(n, CH);
now[now_state] = (now[now_state] + last[k])%1000000007;
} else {
for(l = 1; l <= 4; l++) {
if(CH[j-1] != l && (j == 1 || CH[j-2] != l)) {
tmp = CH[j-1], CH[j-1] = l;
now_state = Calu(n, CH);
now[now_state] = (now[now_state] + last[k])%1000000007;
CH[j-1] = tmp;
}
}
}
}
for(k = 0; k <= state; k++)
last[k] = now[k]%1000000007;
memset(now, 0, sizeof(now));
}
}
int Ans = 0;
for(i = 0; i <= state; i++)
Ans = (Ans+last[i])%1000000007;
printf("Case %d: %d\n", C++, Ans);
}
return 0;
}