给定两个整数N和M ,其中M和N表示维度为N * M的矩阵,仅由0组成。任务是将矩阵的左上角(0, 0)到右下角(N – 1, M – 1)的唯一路径的数量最小化,这些路径跨由 0 组成的单元格,只需在矩阵中精确放置K 个1。
注意:右下角和左上角的单元格都不能修改为 0。
例子:
Input: N = 3, M = 3, K = 1
Output: 2
Explanation:
Placing K(= 1) 1s in the matrix to generate the matrix [[0, 0, 0], [0, 1, 0], [0, 0, 0]] leaves only two possible paths from top-left to bottom-right cells.
The paths are[(0, 0) → (0, 1) → (0, 2) → (1, 2) → (2, 2)] and [(0, 0) → (1, 0) → (2, 0) → (2, 1) → (2, 2)]
Input: N = 3, M = 3, K = 3
Output: 0
Explanation:
Placing K(= 3) 1s to generate a matrix [[0, 1, 1], [1, 0, 0], [0, 0, 0]] leaves no possible path from top-left to bottom-right.
方法:可以通过考虑以下可能的情况来解决该问题。
- 如果 K ≥ 2:通过在矩阵的 (0, 1) 和 (1, 0) 单元格中放置两个 1,可以将可能路径的数量减少到0 。
- 如果 K = 0:计数仍为C(N+M-2, N-1)。
- 如果 K = 1:在矩阵的中心放置一个 1, ((N-1)/2, (M-1)/2)以最小化路径数。因此,这种情况下可能的路径数如下:
Result = Total number of ways to reach the bottom right from the top left – ( Number of paths to midpoint from the top left * Number of ways to reach the endpoint from the midpoint)
where
- Total number of ways to reach the bottom right from the top left = C(N + M – 2, N – 1)
- Number of paths to midpoint from the top left = C((N – 1) / 2 + (M – 1) / 2, (N – 1) / 2)
- Number of ways to reach the endpoint from the midpoint=C(((N – 1) – (N – 1 ) / 2) + ((M – 1) – (M – 1) / 2), ((N – 1) – (N – 1) / 2))
下面是上述方法的实现:
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to return the value of
// Binomial Coefficient C(n, k)
int ncr(int n, int k)
{
int res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate the value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for (int i = 0; i < k; ++i) {
res *= (n - i);
res /= (i + 1);
}
return res;
}
// Function to find the minimum
// count of paths from top
// left to bottom right by
// placing K 1s in the matrix
int countPath(int N, int M, int K)
{
int answer;
if (K >= 2)
answer = 0;
else if (K == 0)
answer = ncr(N + M - 2, N - 1);
else {
// Count of ways without 1s
answer = ncr(N + M - 2, N - 1);
// Count of paths from starting
// point to mid point
int X = (N - 1) / 2 + (M - 1) / 2;
int Y = (N - 1) / 2;
int midCount = ncr(X, Y);
// Count of paths from mid
// point to end point
X = ((N - 1) - (N - 1) / 2)
+ ((M - 1) - (M - 1) / 2);
Y = ((N - 1) - (N - 1) / 2);
midCount *= ncr(X, Y);
answer -= midCount;
}
return answer;
}
// Driver Code
int main()
{
int N = 3;
int M = 3;
int K = 1;
cout << countPath(N, M, K);
return 0;
}
Java
// Java Program to implement
// the above approach
import java.util.*;
class GFG{
// Function to return the value of
// Binomial Coefficient C(n, k)
static int ncr(int n, int k)
{
int res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate the value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for (int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
// Function to find the minimum
// count of paths from top
// left to bottom right by
// placing K 1s in the matrix
static int countPath(int N, int M, int K)
{
int answer;
if (K >= 2)
answer = 0;
else if (K == 0)
answer = ncr(N + M - 2, N - 1);
else
{
// Count of ways without 1s
answer = ncr(N + M - 2, N - 1);
// Count of paths from starting
// point to mid point
int X = (N - 1) / 2 + (M - 1) / 2;
int Y = (N - 1) / 2;
int midCount = ncr(X, Y);
// Count of paths from mid
// point to end point
X = ((N - 1) - (N - 1) / 2) +
((M - 1) - (M - 1) / 2);
Y = ((N - 1) - (N - 1) / 2);
midCount *= ncr(X, Y);
answer -= midCount;
}
return answer;
}
// Driver Code
public static void main(String[] args)
{
int N = 3;
int M = 3;
int K = 1;
System.out.print(countPath(N, M, K));
}
}
// This code is contributed by shikhasingrajput
Python3
#Python3 Program to implement
#the above approach
#Function to return the value of
#Binomial Coefficient C(n, k)
def ncr(n, k):
res = 1
#Since C(n, k) = C(n, n-k)
if (k > n - k):
k = n - k
#Calculate the value of
#[n * (n-1) *---* (n-k+1)] /
#[k * (k-1) *----* 1]
for i in range(k):
res *= (n - i)
res //= (i + 1)
return res
#Function to find the minimum
#count of paths from top
#left to bottom right by
#placing K 1s in the matrix
def countPath(N, M, K):
answer = 0
if (K >= 2):
answer = 0
elif (K == 0):
answer = ncr(N + M - 2, N - 1)
else:
#Count of ways without 1s
answer = ncr(N + M - 2, N - 1)
#Count of paths from starting
#poto mid point
X = (N - 1) // 2 + (M - 1) // 2
Y = (N - 1) // 2
midCount = ncr(X, Y)
#Count of paths from mid
#poto end point
X = ((N - 1) - (N - 1) // 2)+
((M - 1) - (M - 1) // 2)
Y = ((N - 1) - (N - 1) // 2)
midCount *= ncr(X, Y)
answer -= midCount
return answer
#Driver Code
if __name__ == '__main__':
N = 3
M = 3
K = 1
print(countPath(N, M, K))
# This code is contributed by Mohit Kumar 29
C#
// C# program to implemennt
// the above approach
using System;
class GFG{
// Function to return the value of
// Binomial Coefficient C(n, k)
static int ncr(int n, int k)
{
int res = 1;
// Since C(n, k) = C(n, n-k)
if (k > n - k)
k = n - k;
// Calculate the value of
// [n * (n-1) *---* (n-k+1)] /
// [k * (k-1) *----* 1]
for(int i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
// Function to find the minimum
// count of paths from top
// left to bottom right by
// placing K 1s in the matrix
static int countPath(int N, int M, int K)
{
int answer;
if (K >= 2)
answer = 0;
else if (K == 0)
answer = ncr(N + M - 2, N - 1);
else
{
// Count of ways without 1s
answer = ncr(N + M - 2, N - 1);
// Count of paths from starting
// point to mid point
int X = (N - 1) / 2 + (M - 1) / 2;
int Y = (N - 1) / 2;
int midCount = ncr(X, Y);
// Count of paths from mid
// point to end point
X = ((N - 1) - (N - 1) / 2) +
((M - 1) - (M - 1) / 2);
Y = ((N - 1) - (N - 1) / 2);
midCount *= ncr(X, Y);
answer -= midCount;
}
return answer;
}
// Driver Code
public static void Main(String[] args)
{
int N = 3;
int M = 3;
int K = 1;
Console.Write(countPath(N, M, K));
}
}
// This code is contributed by Amit Katiyar
Javascript
2
时间复杂度: O(N+M)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。