给定一个数K,和高度N个酒吧从1到N,任务是找到方法来安排的N个条,使得仅退K棒是从左边可见数量。
例子:
Input: N=4, K=3
Output:
6
Explanation: The 6 permutations where only 3 bars are visible from the left are:
- 1 2 4 3
- 1 3 2 4
- 1 3 4 2
- 2 1 3 4
- 2 3 1 4
- 2 3 4 1
The Underlined bars are not visible.
Input: N=5, K=2
Output:
50
朴素的方法:朴素的方法是检查1 到 N 的所有排列,并检查从左侧可见的条形数量是否为K。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to calculate the number
// of bars that are visible from
// the left for a particular arrangement
int noOfbarsVisibleFromLeft(vector v)
{
int last = 0, ans = 0;
for (auto u : v)
// If current element is greater
// than the last greater element,
// it is visible
if (last < u) {
ans++;
last = u;
}
return ans;
}
// Function to calculate the number
// of rearrangements where
// K bars are visiblef from the left
int KvisibleFromLeft(int N, int K)
{
// Vector to store current permutation
vector v(N);
for (int i = 0; i < N; i++)
v[i] = i + 1;
int ans = 0;
// Check for all permutations
do {
// If current permutation meets
// the conditions, increment answer
if (noOfbarsVisibleFromLeft(v) == K)
ans++;
} while (next_permutation(v.begin(), v.end()));
return ans;
}
// Driver code
int main()
{
// Input
int N = 5, K = 2;
// Function call
cout << KvisibleFromLeft(N, K) << endl;
return 0;
}
Python3
# Python3 program for the above approach
# Function to calculate the number
# of bars that are visible from
# the left for a particular arrangement
def noOfbarsVisibleFromLeft(v):
last = 0
ans = 0
for u in v:
# If current element is greater
# than the last greater element,
# it is visible
if (last < u):
ans += 1
last = u
return ans
def nextPermutation(nums):
i = len(nums) - 2
while i > -1:
if nums[i] < nums[i + 1]:
j = len(nums) - 1
while j > i:
if nums[j] > nums[i]:
break
j -= 1
nums[i], nums[j] = nums[j], nums[i]
break
i -= 1
nums[i + 1:] = reversed(nums[i + 1:])
return nums
# Function to calculate the number
# of rearrangements where
# K bars are visiblef from the left
def KvisibleFromLeft(N, K):
# Vector to store current permutation
v = [0]*(N)
for i in range(N):
v[i] = i + 1
ans = 0
temp = list(v)
# Check for all permutations
while True:
# If current permutation meets
# the conditions, increment answer
if (noOfbarsVisibleFromLeft(v) == K):
ans += 1
v = nextPermutation(v)
if v == temp:
break
return ans
# Driver code
if __name__ == '__main__':
# Input
N = 5
K = 2
# Function call
print (KvisibleFromLeft(N, K))
# This code is contributed by mohit kumar 29.
C++
// C++ implementation for the above approach
#include
using namespace std;
// Function to calculate the number of permutations of
// N, where only K bars are visible from the left.
int KvisibleFromLeft(int N, int K)
{
// Only ascending order is possible
if (N == K)
return 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1) {
int ans = 1;
for (int i = 1; i < N; i++)
ans *= i;
return ans;
}
// Recursing
return KvisibleFromLeft(N - 1, K - 1)
+ (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
int main()
{
// Input
int N = 5, K = 2;
// Function call
cout << KvisibleFromLeft(N, K) << endl;
return 0;
}
Java
// Java program for the above approach
class GFG{
// Function to calculate the number of
// permutations of N, where only K bars
// are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
// Only ascending order is possible
if (N == K)
return 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1)
{
int ans = 1;
for(int i = 1; i < N; i++)
ans *= i;
return ans;
}
// Recursing
return KvisibleFromLeft(N - 1, K - 1) +
(N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
public static void main(String[] args)
{
// Input
int N = 5, K = 2;
// Function call
System.out.println(KvisibleFromLeft(N, K));
}
}
// This code is contributed by abhinavjain194
Python3
# Python 3 implementation for the above approach
# Function to calculate the number of permutations of
# N, where only K bars are visible from the left.
def KvisibleFromLeft(N, K):
# Only ascending order is possible
if (N == K):
return 1
# N is placed at the first position
# The nest N-1 are arranged in (N-1)! ways
if (K == 1):
ans = 1
for i in range(1, N, 1):
ans *= i
return ans
# Recursing
return KvisibleFromLeft(N - 1, K - 1) + (N - 1) * KvisibleFromLeft(N - 1, K)
# Driver code
if __name__ == '__main__':
# Input
N = 5
K = 2
# Function call
print(KvisibleFromLeft(N, K))
# This code is contributed by ipg2016107.
C#
// C# program for the above approach
using System;
class GFG
{
// Function to calculate the number of
// permutations of N, where only K bars
// are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
// Only ascending order is possible
if (N == K)
return 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1)
{
int ans = 1;
for(int i = 1; i < N; i++)
ans *= i;
return ans;
}
// Recursing
return KvisibleFromLeft(N - 1, K - 1) +
(N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
public static void Main(String[] args)
{
// Input
int N = 5, K = 2;
// Function call
Console.Write(KvisibleFromLeft(N, K));
}
}
// This code is contributed by shivanisinghss2110
Javascript
C++
// C++ implementation for the above approach
#include
using namespace std;
// dp array
int dp[1005][1005];
// Function to calculate the number
// of permutations of N, where
// only K bars are visible from the left.
int KvisibleFromLeft(int N, int K)
{
// If subproblem has already
// been calculated, return
if (dp[N][K] != -1)
return dp[N][K];
// Only ascending order is possible
if (N == K)
return dp[N][K] = 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1) {
int ans = 1;
for (int i = 1; i < N; i++)
ans *= i;
return dp[N][K] = ans;
}
// Recursing
return dp[N][K]
= KvisibleFromLeft(N - 1, K - 1)
+ (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
int main()
{
// Input
int N = 5, K = 2;
// Initialize dp array
memset(dp, -1, sizeof(dp));
// Function call
cout << KvisibleFromLeft(N, K) << endl;
return 0;
}
C#
// C# implementation for the above approach
using System;
public class GFG{
// dp array
static int [,]dp = new int[1005, 1005];
// Function to calculate the number
// of permutations of N, where
// only K bars are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
// If subproblem has already
// been calculated, return
if (dp[N ,K] != -1)
return dp[N,K];
// Only ascending order is possible
if (N == K)
return dp[N,K] = 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1) {
int ans = 1;
for (int i = 1; i < N; i++)
ans *= i;
return dp[N,K] = ans;
}
// Recursing
return dp[N,K]
= KvisibleFromLeft(N - 1, K - 1)
+ (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
public static void Main(String[] args)
{
// Input
int N = 5, K = 2;
// Initialize dp array
for(int i = 0; i < 1005; i++)
{
for (int j = 0; j < 1005; j++)
{
dp[i, j] = -1;
}
}
// Function call
Console.Write( KvisibleFromLeft(N, K));
}
}
// This code is contributed by shivanisinghss2110
Javascript
Java
// Java implementation for the above approach
import java.util.*;
class GFG{
// dp array
static int [][]dp = new int[1005][1005];
// Function to calculate the number
// of permutations of N, where
// only K bars are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
// If subproblem has already
// been calculated, return
if (dp[N][K] != -1)
return dp[N][K];
// Only ascending order is possible
if (N == K)
return dp[N][K] = 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1) {
int ans = 1;
for (int i = 1; i < N; i++)
ans *= i;
return dp[N][K] = ans;
}
// Recursing
return dp[N][K]
= KvisibleFromLeft(N - 1, K - 1)
+ (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
public static void main(String[] args)
{
// Input
int N = 5, K = 2;
// Initialize dp array
for(int i = 0; i < 1005; i++)
{
for (int j = 0; j < 1005; j++)
{
dp[i][j] = -1;
}
}
// Function call
System.out.print( KvisibleFromLeft(N, K));
}
}
// This code is contributed by shivanisinghss2110
输出
50
时间复杂度: O(N!)
辅助空间: O(N)
有效的方法:有效的方法是使用递归。请按照以下步骤解决问题:
- 创建一个递归函数KvisibleFromLeft() ,它将N和K作为输入参数并执行以下操作:
- 基本情况:
- 如果N等于K ,则有一种排列条形的方法,即按升序排列。所以,返回1 。
- 如果K==1 ,则有(N-1) 个!条的排列方式,因为最长的条放在第一个位置,剩余的N-1 个条可以放在剩余的N-1 个位置的任何位置。所以,返回(N-1)! .
- 对于递归,有两种情况:
- 可以将最小的条放在第一个位置,然后在剩余的N-1 个条中,只需要显示K-1 个条。因此,答案将与排列N-1 个条形以使K-1 个条形可见的方法数量相同。因此,这种情况会递归调用KvisibleFromLeft(N-1, K-1) 。
- 最小的条可以放置在N-1 个位置中的任何一个,除了第一个。这将隐藏最小的条形,因此,答案将与排列N-1 个条形以使K 个条形可见的方法数量相同。因此,这种情况递归地调用(N-1)*KvisibleFromLeft(N-1,K)。
- 基本情况:
下面是上述方法的实现:
C++
// C++ implementation for the above approach
#include
using namespace std;
// Function to calculate the number of permutations of
// N, where only K bars are visible from the left.
int KvisibleFromLeft(int N, int K)
{
// Only ascending order is possible
if (N == K)
return 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1) {
int ans = 1;
for (int i = 1; i < N; i++)
ans *= i;
return ans;
}
// Recursing
return KvisibleFromLeft(N - 1, K - 1)
+ (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
int main()
{
// Input
int N = 5, K = 2;
// Function call
cout << KvisibleFromLeft(N, K) << endl;
return 0;
}
Java
// Java program for the above approach
class GFG{
// Function to calculate the number of
// permutations of N, where only K bars
// are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
// Only ascending order is possible
if (N == K)
return 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1)
{
int ans = 1;
for(int i = 1; i < N; i++)
ans *= i;
return ans;
}
// Recursing
return KvisibleFromLeft(N - 1, K - 1) +
(N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
public static void main(String[] args)
{
// Input
int N = 5, K = 2;
// Function call
System.out.println(KvisibleFromLeft(N, K));
}
}
// This code is contributed by abhinavjain194
蟒蛇3
# Python 3 implementation for the above approach
# Function to calculate the number of permutations of
# N, where only K bars are visible from the left.
def KvisibleFromLeft(N, K):
# Only ascending order is possible
if (N == K):
return 1
# N is placed at the first position
# The nest N-1 are arranged in (N-1)! ways
if (K == 1):
ans = 1
for i in range(1, N, 1):
ans *= i
return ans
# Recursing
return KvisibleFromLeft(N - 1, K - 1) + (N - 1) * KvisibleFromLeft(N - 1, K)
# Driver code
if __name__ == '__main__':
# Input
N = 5
K = 2
# Function call
print(KvisibleFromLeft(N, K))
# This code is contributed by ipg2016107.
C#
// C# program for the above approach
using System;
class GFG
{
// Function to calculate the number of
// permutations of N, where only K bars
// are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
// Only ascending order is possible
if (N == K)
return 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1)
{
int ans = 1;
for(int i = 1; i < N; i++)
ans *= i;
return ans;
}
// Recursing
return KvisibleFromLeft(N - 1, K - 1) +
(N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
public static void Main(String[] args)
{
// Input
int N = 5, K = 2;
// Function call
Console.Write(KvisibleFromLeft(N, K));
}
}
// This code is contributed by shivanisinghss2110
Javascript
输出
50
时间复杂度: O(2 N )
辅助空间: O(1)
有效方法:上述递归可以记忆,因此可以使用动态规划,因为存在最佳子结构。
下面是上述方法的实现:
C++
// C++ implementation for the above approach
#include
using namespace std;
// dp array
int dp[1005][1005];
// Function to calculate the number
// of permutations of N, where
// only K bars are visible from the left.
int KvisibleFromLeft(int N, int K)
{
// If subproblem has already
// been calculated, return
if (dp[N][K] != -1)
return dp[N][K];
// Only ascending order is possible
if (N == K)
return dp[N][K] = 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1) {
int ans = 1;
for (int i = 1; i < N; i++)
ans *= i;
return dp[N][K] = ans;
}
// Recursing
return dp[N][K]
= KvisibleFromLeft(N - 1, K - 1)
+ (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
int main()
{
// Input
int N = 5, K = 2;
// Initialize dp array
memset(dp, -1, sizeof(dp));
// Function call
cout << KvisibleFromLeft(N, K) << endl;
return 0;
}
C#
// C# implementation for the above approach
using System;
public class GFG{
// dp array
static int [,]dp = new int[1005, 1005];
// Function to calculate the number
// of permutations of N, where
// only K bars are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
// If subproblem has already
// been calculated, return
if (dp[N ,K] != -1)
return dp[N,K];
// Only ascending order is possible
if (N == K)
return dp[N,K] = 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1) {
int ans = 1;
for (int i = 1; i < N; i++)
ans *= i;
return dp[N,K] = ans;
}
// Recursing
return dp[N,K]
= KvisibleFromLeft(N - 1, K - 1)
+ (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
public static void Main(String[] args)
{
// Input
int N = 5, K = 2;
// Initialize dp array
for(int i = 0; i < 1005; i++)
{
for (int j = 0; j < 1005; j++)
{
dp[i, j] = -1;
}
}
// Function call
Console.Write( KvisibleFromLeft(N, K));
}
}
// This code is contributed by shivanisinghss2110
Javascript
Java
// Java implementation for the above approach
import java.util.*;
class GFG{
// dp array
static int [][]dp = new int[1005][1005];
// Function to calculate the number
// of permutations of N, where
// only K bars are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
// If subproblem has already
// been calculated, return
if (dp[N][K] != -1)
return dp[N][K];
// Only ascending order is possible
if (N == K)
return dp[N][K] = 1;
// N is placed at the first position
// The nest N-1 are arranged in (N-1)! ways
if (K == 1) {
int ans = 1;
for (int i = 1; i < N; i++)
ans *= i;
return dp[N][K] = ans;
}
// Recursing
return dp[N][K]
= KvisibleFromLeft(N - 1, K - 1)
+ (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
public static void main(String[] args)
{
// Input
int N = 5, K = 2;
// Initialize dp array
for(int i = 0; i < 1005; i++)
{
for (int j = 0; j < 1005; j++)
{
dp[i][j] = -1;
}
}
// Function call
System.out.print( KvisibleFromLeft(N, K));
}
}
// This code is contributed by shivanisinghss2110
输出
50
时间复杂度: O(NK)
辅助空间: O(NK)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。