求问个算法有关问题,题目如下

求问个算法问题,题目如下
硬解我能解出来 但是总是超时 实在想不出什么优化的算法了
http://oj.hi-hi.cn/JudgeOnline/problem.php?cid=1117&pid=10
------解决思路----------------------
求问个算法有关问题,题目如下超时是必须的:
//问题 K: 清障碍
//时间限制: 4 Sec  内存限制: 32 MB
//题目描述
//游戏是一个5行4列的方格阵列,有些格子有障碍物,有些没有,过关是要求所有的障碍物被清除.
//Ada只能在没有障碍物的格子放置炸弹, 炸弹会清除东南西北四个方向上的相邻格子的障碍物.
//也就是,如果无障碍物的格子座标是(x,y), 则(x+1, y),(x-1,y),(x,y+1),(x,y-1)四个相邻格
//的障碍物(如果有的话)都会清除, 座标越界的情况不需要考虑.
//为了挽救沉迷游戏的Ada, 规定Ada每过一关必须用最少的炸弹,否则就收缴手机让她没得玩.
//如下图的局面(1表示障碍),只需要一个炸弹即可
//0000
//0100
//1010
//0100
//0000
//显然Ada处理不了这么复杂的问题,帮帮她吧
//输入
// 由不超过20000组测试数据组成,格式参见样例. 每组测试数据的第一行是"Case 编号:"的形式,
// 随后有5行4列的方格阵,0表示格子无障碍,1表示有障碍. 保证不会出现格子全部都是障碍的清空.
//输出
// 每组数据输出一行,包含清除所有障碍所需要的最少炸弹数目,格式参见样例.
//
//样例输入
//Case 1:
//1000
//0000
//0000
//0000
//0000
//Case 2:
//1100
//0000
//0000
//0000
//0000
//Case 3:
//1010
//0000
//0000
//0000
//0000
//样例输出
//The result of case 1 is 1
//The result of case 2 is 2
//The result of case 3 is 1
//
//思路:
//保存现场
//测试下一个1旁边的0
//模拟爆炸
//若全0,记录本轮共炸几次,恢复现场,递归
//若非全0,递归
#include <stdio.h>
#include <string.h>
int minb;
int ok(int y,int x) {
    if (0<=y && y<5 && 0<=x && x<4) return 1;
    else return 0;
}
int clean(char m[5][6]) {
    int y,x;

    for (y=0;y<5;y++) {
        for (x=0;x<4;x++) {
            if ('0'!=m[y][x]) return 0;
        }
    }
    return 1;
}
void bomb(char m[5][6],int y,int x,char n[5][6]) {
    memcpy((void *)n,(void *)m,30);
    if (ok(y-1,x)) n[y-1][x]='0';
    if (ok(y+1,x)) n[y+1][x]='0';
    if (ok(y,x-1)) n[y][x-1]='0';
    if (ok(y,x+1)) n[y][x+1]='0';
}
void bomball(char m[5][6],int b) {//b为已放炸弹总数
    char c;
    char M[5][6];
    char N[5][6];
    int y,x,d,yy,xx;

    memcpy((void *)M,(void *)m,30);
    for (y=0;y<5;y++) {
        for (x=0;x<4;x++) {
            c=M[y][x];
            if ('0'!=c) {
                for (d=0;d<4;d++) {
                    switch (d) {
                        case 0:yy=y-1;xx=x;break;
                        case 1:yy=y+1;xx=x;break;
                        case 2:yy=y;xx=x-1;break;
                        case 3:yy=y;xx=x+1;break;
                    }
                    if (ok(yy,xx)) {
                        c=M[yy][xx];
                        if ('0'==c) {
                            b++;
                            bomb(M,yy,xx,N);
                            if (clean(N)) {
                                if (b<minb) minb=b;
                                b--;
                            } else {
                                memcpy((void *)M,(void *)N,30);
                                bomball(M,b);
                            }
                        }
                    }
                }
            }
        }
    }
    if (b<minb) minb=b;
}
int main() {
    char ln[16];
    int n;
    char c;
    char m[5][6];
    int y;

    while (1) {
        if (NULL==fgets(ln,16,stdin)) break;
        if ('\n'==ln[0]) break;
        if (2!=sscanf(ln,"Case %d%c",&n,&c)) break;
        if (':'!=c) break;
        for (y=0;y<5;y++) {
            if (NULL==fgets(m[y],6,stdin)) break;
        }
        if (y<5) break;
        minb=20;
        bomball(m,0);
        printf("The result of case %d is %d\n",n,minb);
    }
    return 0;
}

等楼下高手改动态规划中……求问个算法有关问题,题目如下