我有一个二阶矩阵(M x N),其中所有单元格都包含0,除了K特殊单元格,其中包含一个特殊值,即1.现在我需要从单元格开始说(0,0)并到达单元格(M-1,N-1)。我只能从任何细胞向右或向下移动。现在我需要找到(M-1,N-1)细胞的每个成功范围,我收集了多少特殊值以及它们的频率是多少?示例:我可以说3个路径只包含一个特殊值,我有10个路径,其中包含2个特殊值...依此类推。
我需要打印以相应频率获得的所有可能的总特殊价值对,即; (2,10) - 表示有2条路径,每条路的总特殊值为10等。
似乎找出从源到目的地的所有dfs路径,并计算从源到目的地获得的总特殊值的频率。但它的时间复杂度非常高。
如何最小化时间复杂度或如果可能的话如何使用动态编程概念?
示例:
0 0 0
0 1 1
0 0 0
答案 0 :(得分:0)
在这个问题中,通过简单地转换图形,很容易消除可能的路径。
将矩阵转换为有向图,其中每个节点都是一个特殊值。每个节点(nx , ny)
仅与匹配(mx , my)
nx <= mx && ny <= my && !(nx == mx && ny == my)
相关联
int[][] matrix = getMatrix()
int specialNumberCount = specialNumberCount()
int m = getM(), n = getN()
list points
for int x in [0 , m[
for int y in [0 , n[
if(matrix[x][y] == specialValue())
points.add(point(x , y));
int[][] adjacencSpecial = new int[specialNumberCount][specialNumberCount];
for int i in [0 , length(points)[
point p = points.get(i)
for int j in [0 , length(points)[
if j == i
continue
else
point s = points.get(j)
if p.x <= s.x AND p.y <= s.y AND (p.x != s.x AND p.y != s.y)
adjacencMatrix[i][j] = 1
现在,此代码会将图表的大小从M x N
缩小为K
。从这一点来说,运行BFS并不需要太长时间。
答案 1 :(得分:0)
不知道你是否仍然需要它,但发现了一种非常快速的方法(时间复杂度小于O(W+H)
):
首先,通过向右移动移动次数(c(W+H-2,W-1)
)找到移动次数的二项式系数,找到可能路径的数量,然后遍历每条路径,存储这些点供以后使用。
代码:
//
// main.c
//
// Created by Xavier L'Heureux on 15-10-01.
//
// This code return the number of path for each possible value in the matrix where you can only
// go down or right.
//
// Note that this code work also for for non-square matrices
//
#include <stdio.h>
#include <stdlib.h>
#define W 3
#define H 4
int matrix[W][H] = {
{0,0,0,0},
{0,0,1,1},
{0,0,0,0}
};
int path(double p, double n){
int x = W - 1, y = H - 1;
int points = 0;
while (x != 0 || y != 0){
//printf("\np: %f\nn: %f\n", p, n);
if (x == 0){
y --;
points += matrix[x][y];
} else if (y == 0){
x --;
points += matrix[x][y];
} else if (p / n >= y / (double)(x + y)){
p -= n * y / (x + y);
n -= n * y / (x + y);
points += matrix[x][y];
x --;
} else {
n -= n * x / (x + y);
points += matrix[x][y];
y --;
}
}
return points;
}
double c(int n, int k){
double x = 1.0;
int i;
for (i = n; i > (n-k); i--){
x *= i;
}
for (i = 1; i <= k; i++){
x /= i;
}
return x;
}
int numOfPoints(){
int points = 0;
int x, y;
for (x = 0; x < W; x++) {
for (y = 0; y < W; y++) {
points += matrix[x][y];
}
}
return points;
}
int main (int argc, const char * argv[])
{
int n = c(W + H - 2, W - 1);
printf("%d path(s)",n);
int maxPoints = numOfPoints() + 1;
int *countPtr = (int *)calloc(maxPoints, sizeof (int));
int i;
for (i = 0; i < n; i++){
countPtr[path(i, n)]++;
}
for (i = 0; i <= maxPoints; i++){
printf("n° of path(s) with %d point(s) : \t%d\n", i, countPtr[i]);
}
free(countPtr);
return 0;
}