给定一个具有N 个节点和N*(N-1)/2 条边和一个正整数K的完整图,任务是找到从节点1开始并在同一节点结束(如果正好有K 条边)的方法数必须遍历。
Input: N = 4, K = 3
Output: 6
Explanation: The possible ways are-
1→2→3→1
1→2→4→1
1→3→2→1
1→3→4→1
1→4→2→1
1→4→3→1
Input: N = 5, K = 3
Output: 12
朴素的方法:解决这个问题的最简单的方法是从当前顶点开始遍历每条边,它将导致解决方案的指数时间。
时间复杂度: O(N^N)
辅助空间: O(N),由于递归函数调用中的堆栈空间。
高效方法:这个问题具有重叠子问题属性和最优子结构属性。所以这个问题可以用动态规划解决。与其他典型的动态规划 (DP) 问题一样,可以通过构造一个存储子问题结果的临时数组来避免对相同子问题的重新计算。请按照以下步骤解决问题:
- 初始化一个dp[]数组,其中dp[i]存储到达第 i 个节点的路径数,并将dp[0]初始化为1。
- 使用变量i在范围[1, K] 中迭代并执行以下步骤:
- 将变量numWays初始化为0到 存储到达所有节点的方法数。
- 使用变量j在范围[0, N-1] 中迭代,然后在numWays 中添加dp[j] 。
- 使用变量j在范围[0, N-1] 中迭代,然后将dp[j]的值更新为dp[j]和numWays – dp[j] 的最大值。
- 执行上述步骤后,打印dp[0]作为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find number of ways to
// reach from node 1 to 1 again, after
// moving exactly K edges
void numberOfWays(int n, int k)
{
// Initialize a dp[] array, where dp[i]
// stores number of ways to reach at
// a i node
int dp[1000];
// Initialize the dp array with 0
for (int i = 0; i < n; i++) {
dp[i] = 0;
}
// Base Case
dp[0] = 1;
// Iterate for the number of edges moved
for (int i = 1; i <= k; i++) {
// Sum will store number of ways to
// reach all the nodes
int numWays = 0;
// Iterate for every possible state
// for the current step
for (int j = 0; j < n; j++) {
numWays += dp[j];
}
// Update the value of the dp array
// after travelling each edge
for (int j = 0; j < n; j++) {
dp[j] = numWays - dp[j];
}
}
// Print dp[0] as the answer
cout << dp[0] << endl;
}
// Driver Code
int main()
{
// Given Input
int N = 5, K = 3;
// Function Call
numberOfWays(N, K);
return 0;
}
Java
// Java program for the above approach
class GFG{
// Function to find number of ways to
// reach from node 1 to 1 again, after
// moving exactly K edges
static void numberOfWays(int n, int k)
{
// Initialize a dp[] array, where dp[i]
// stores number of ways to reach at
// a i node
int[] dp = new int[1000];
// Initialize the dp array with 0
for(int i = 0; i < n; i++)
{
dp[i] = 0;
}
// Base Case
dp[0] = 1;
// Iterate for the number of edges moved
for(int i = 1; i <= k; i++)
{
// Sum will store number of ways to
// reach all the nodes
int numWays = 0;
// Iterate for every possible state
// for the current step
for(int j = 0; j < n; j++)
{
numWays += dp[j];
}
// Update the value of the dp array
// after travelling each edge
for(int j = 0; j < n; j++)
{
dp[j] = numWays - dp[j];
}
}
// Print dp[0] as the answer
System.out.println(dp[0] + "\n");
}
// Driver Code
public static void main(String args[])
{
// Given Input
int N = 5, K = 3;
// Function Call
numberOfWays(N, K);
}
}
// This code is contributed by _saurabh_jaiswal
Python3
# Python 3 program for the above approach
# Function to find number of ways to
# reach from node 1 to 1 again, after
# moving exactly K edges
def numberOfWays(n, k):
# Initialize a dp[] array, where dp[i]
# stores number of ways to reach at
# a i node
dp = [0 for i in range(1000)]
# Base Case
dp[0] = 1
# Iterate for the number of edges moved
for i in range(1, k + 1, 1):
# Sum will store number of ways to
# reach all the nodes
numWays = 0
# Iterate for every possible state
# for the current step
for j in range(n):
numWays += dp[j]
# Update the value of the dp array
# after travelling each edge
for j in range(n):
dp[j] = numWays - dp[j]
# Print dp[0] as the answer
print(dp[0])
# Driver Code
if __name__ == '__main__':
# Given Input
N = 5
K = 3
# Function Call
numberOfWays(N, K)
# This code is contributed by SURENDRA_GANGWAR.
C#
// C# program for the above approach
using System;
class GFG{
// Function to find number of ways to
// reach from node 1 to 1 again, after
// moving exactly K edges
static void numberOfWays(int n, int k)
{
// Initialize a dp[] array, where dp[i]
// stores number of ways to reach at
// a i node
int[] dp = new int[1000];
// Initialize the dp array with 0
for(int i = 0; i < n; i++)
{
dp[i] = 0;
}
// Base Case
dp[0] = 1;
// Iterate for the number of edges moved
for(int i = 1; i <= k; i++)
{
// Sum will store number of ways to
// reach all the nodes
int numWays = 0;
// Iterate for every possible state
// for the current step
for(int j = 0; j < n; j++)
{
numWays += dp[j];
}
// Update the value of the dp array
// after travelling each edge
for(int j = 0; j < n; j++)
{
dp[j] = numWays - dp[j];
}
}
// Print dp[0] as the answer
Console.Write(dp[0]);
}
// Driver Code
static public void Main ()
{
// Given Input
int N = 5, K = 3;
// Function Call
numberOfWays(N, K);
}
}
// This code is contributed by sanjoy_62
Javascript
12
时间复杂度: O(N×K)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。