给定一个整数N ,任务是计算可能的整数[1, N]的单峰和非单峰排列的总数。
An unimodal permutation is a permutation which increases up to a certain point following which it starts decreasing.
All other permutations, excluding unimodal permutations, are non-unimodal permutations.
注意:由于总计数可能非常大,所以打印模 10 9 +7。
例子:
Input: N = 3
Output: 4 2
Explanation:
All possible unimodal permutations are {1, 2, 3}, {1, 3, 2}, {2, 3, 1}, {3, 2, 1}.
Therefore, the count of unimodal permutations is 4.
Remaining permutations are {2, 1, 3}, {3, 1, 2}.
Therefore, the count of non-unimodal permutations is 2.
Input: N = 4
Output: 8 16
朴素的方法:最简单的方法是从范围[1, N]生成所有可能的整数排列,然后打印所有这些单峰排列的计数。相应地打印单峰和非单峰排列的计数。
时间复杂度: O(N!)
辅助空间: O(N)
有效的方法:为了优化上述方法,其思想是首先找到给定整数N可能的单峰排列总数,然后找到非单峰排列的计数,以从总数中减去单峰排列的计数排列。以下是步骤:
- 在无限长度数组中构造长度为N 的单峰排列。
- 将N放置在排列中的任何位置,那么正好有两个位置可以放置第(N – 1)个元素,即N的左侧或右侧。
- 假设它向右移动。现在,第(N – 2)个元素可以放在当前排列的左侧或右侧。
- 这对于所有元素一直持续到 1。请注意,除了N之外,每个元素都有两个选择。
- 因此,长度为N的单峰排列的数量将为2 N – 1
- 排列的总数将为N! .
- 现在非单峰排列的总数将等于(N! – 单峰排列)。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
int mod = 1e9 + 7;
const int mx = 1e6;
int fact[mx + 1];
// Function to calculate the
// factorials up to a number
void Calculate_factorial()
{
fact[0] = 1;
// Calculate the factorial
for (int i = 1; i <= mx; i++) {
fact[i] = i * fact[i - 1];
fact[i] %= mod;
}
}
// Function to find power(a, b)
int UniModal_per(int a, int b)
{
long long int res = 1;
// Iterate until b exists
while (b) {
// If b is divisible by 2
if (b % 2)
res = res * a;
res %= mod;
a = a * a;
a %= mod;
// Decrease the value of b
b /= 2;
}
// Return the answer
return res;
}
// Function that counts the unimodal
// and non-unimodal permutations of
// a given integer N
void countPermutations(int n)
{
// Function Call for finding
// factorials up to N
Calculate_factorial();
// Function to count unimodal
// permutations
int uni_modal = UniModal_per(2, n - 1);
// Non-unimodal permutation is
// N! - unimodal permutations
int nonuni_modal = fact[n] - uni_modal;
cout << uni_modal << " " << nonuni_modal;
return;
}
// Driver Code
int main()
{
// Given Number N
int N = 4;
// Function Call
countPermutations(N);
return 0;
}
Java
// Java program for
// the above approach
class GFG {
static int mod = (int)(1e9 + 7);
static int mx = (int)1e6;
static int[] fact = new int[(int)mx + 1];
// Function to calculate the
// factorials up to a number
static void Calculate_factorial()
{
fact[0] = 1;
// Calculate the factorial
for (int i = 1; i <= mx; i++) {
fact[i] = i * fact[i - 1];
fact[i] %= mod;
}
}
// Function to find power(a, b)
static int UniModal_per(int a, int b)
{
int res = 1;
// Iterate until b exists
while (b > 0) {
// If b is divisible by 2
if (b % 2 != 0)
res = res * a;
res %= mod;
a = a * a;
a %= mod;
// Decrease the value of b
b /= 2;
}
// Return the answer
return res;
}
// Function that counts the unimodal
// and non-unimodal permutations of
// a given integer N
static void countPermutations(int n)
{
// Function Call for finding
// factorials up to N
Calculate_factorial();
// Function to count unimodal
// permutations
int uni_modal = UniModal_per(2, n - 1);
// Non-unimodal permutation is
// N! - unimodal permutations
int nonuni_modal = fact[n] - uni_modal;
System.out.print(uni_modal + " " + nonuni_modal);
return;
}
// Driver Code
public static void main(String[] args)
{
// Given Number N
int N = 4;
// Function Call
countPermutations(N);
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program for the above approach
mod = 1e9 + 7
mx = 1000000
fact = [0] * (mx + 1)
# Function to calculate the
# factorials up to a number
def Calculate_factorial():
fact[0] = 1
# Calculate the factorial
for i in range(1, mx + 1):
fact[i] = i * fact[i - 1]
fact[i] %= mod
# Function to find power(a, b)
def UniModal_per(a, b):
res = 1
# Iterate until b exists
while (b != 0):
# If b is divisible by 2
if (b % 2 != 0):
res = res * a
res %= mod
a = a * a
a %= mod
# Decrease the value of b
b //= 2
# Return the answer
return res
# Function that counts the unimodal
# and non-unimodal permutations of
# a given integer N
def countPermutations(n):
# Function Call for finding
# factorials up to N
Calculate_factorial()
# Function to count unimodal
# permutations
uni_modal = UniModal_per(2, n - 1)
# Non-unimodal permutation is
# N! - unimodal permutations
nonuni_modal = fact[n] - uni_modal
print(int(uni_modal), "",
int(nonuni_modal))
return
# Driver Code
# Given number N
N = 4
# Function call
countPermutations(N)
# This code is contributed by code_hunt
C#
// C# program for
// the above approach
using System;
class GFG
{
static int mod = (int)(1e9 + 7);
static int mx = (int)1e6;
static int[] fact = new int[(int)mx + 1];
// Function to calculate the
// factorials up to a number
static void Calculate_factorial()
{
fact[0] = 1;
// Calculate the factorial
for (int i = 1; i <= mx; i++)
{
fact[i] = i * fact[i - 1];
fact[i] %= mod;
}
}
// Function to find power(a, b)
static int UniModal_per(int a, int b)
{
int res = 1;
// Iterate until b exists
while (b > 0)
{
// If b is divisible by 2
if (b % 2 != 0)
res = res * a;
res %= mod;
a = a * a;
a %= mod;
// Decrease the value of b
b /= 2;
}
// Return the answer
return res;
}
// Function that counts the unimodal
// and non-unimodal permutations of
// a given integer N
static void countPermutations(int n)
{
// Function Call for finding
// factorials up to N
Calculate_factorial();
// Function to count unimodal
// permutations
int uni_modal = UniModal_per(2, n - 1);
// Non-unimodal permutation is
// N! - unimodal permutations
int nonuni_modal = fact[n] - uni_modal;
Console.Write(uni_modal + " " + nonuni_modal);
return;
}
// Driver Code
public static void Main(String[] args)
{
// Given Number N
int N = 4;
// Function Call
countPermutations(N);
}
}
// This code is contributed by shikhasingrajput
Javascript
8 16
时间复杂度: O(N)
辅助空间: O(N)