给定N个块,其中K是彩色的。这些 K 色块由数组arr[] 表示。任务是计算为剩余的未着色块着色的方法的数量,以便在一个步骤中只有一个着色块的相邻块中的任何一个可以着色。用模 10 9 +7 打印答案。
例子:
Input: N = 6, K = 3, arr[] = {1, 2, 6}
Output: 4
Explanation:
The following are the 4 ways to color the blocks(each set reblockquotesents the order in which blocks are colored):
1. {3, 4, 5}
2. {3, 5, 4}
3. {5, 3, 4}
4. {5, 4, 3}
Input: N = 9, K = 3, A = [3, 6, 7]
Output: 180
朴素的方法:这个想法是使用递归。以下是步骤:
- 从 1 到 N 遍历每个块。
- 如果当前块(例如b )未着色,则检查相邻块之一是否着色。
- 如果相邻块被着色,则为当前块着色并递归迭代以找到下一个未着色的块。
- 在上述递归调用结束后,对blockquotevious递归调用的block进行uncolored,对下一个uncolored block重复上述步骤。
- 在所有上述递归调用中为块着色的计数给出了为未着色块着色的方法数。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
const int mod = 1000000007;
// Recursive function to count the ways
int countWays(int colored[], int count,
int n)
{
// Base case
if (count == n) {
return 1;
}
// Initialise answer to 0
int answer = 0;
// Color each uncolored block according
// to the given condition
for (int i = 1; i < n + 1; i++) {
// If any block is uncolored
if (colored[i] == 0) {
// Check if adjacent blocks
// are colored or not
if (colored[i - 1] == 1
|| colored[i + 1] == 1) {
// Color the block
colored[i] = 1;
// recursively iterate for
// next uncolored block
answer = (answer
+ countWays(colored,
count + 1,
n))
% mod;
// Uncolored for the next
// recursive call
colored[i] = 0;
}
}
}
// Return the final count
return answer;
}
// Function to count the ways to color
// block
int waysToColor(int arr[], int n, int k)
{
// Mark which blocks are colored in
// each recursive step
int colored[n + 2] = { 0 };
for (int i = 0; i < k; i++) {
colored[arr[i]] = 1;
}
// Function call to count the ways
return countWays(colored, k, n);
}
// Driver Code
int main()
{
// Number of blocks
int N = 6;
// Number of colored blocks
int K = 3;
int arr[K] = { 1, 2, 6 };
// Function call
cout << waysToColor(arr, N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static int mod = 1000000007;
// Recursive function to count the ways
static int countWays(int colored[],
int count, int n)
{
// Base case
if (count == n)
{
return 1;
}
// Initialise answer to 0
int answer = 0;
// Color each uncolored block according
// to the given condition
for (int i = 1; i < n + 1; i++)
{
// If any block is uncolored
if (colored[i] == 0)
{
// Check if adjacent blocks
// are colored or not
if (colored[i - 1] == 1 ||
colored[i + 1] == 1)
{
// Color the block
colored[i] = 1;
// recursively iterate for
// next uncolored block
answer = (answer +
countWays(colored,
count + 1,
n)) % mod;
// Uncolored for the next
// recursive call
colored[i] = 0;
}
}
}
// Return the final count
return answer;
}
// Function to count the ways to color
// block
static int waysToColor(int arr[],
int n, int k)
{
// Mark which blocks are colored in
// each recursive step
int colored[] = new int[n + 2];
for (int i = 0; i < k; i++)
{
colored[arr[i]] = 1;
}
// Function call to count the ways
return countWays(colored, k, n);
}
// Driver Code
public static void main(String[] args)
{
// Number of blocks
int N = 6;
// Number of colored blocks
int K = 3;
int arr[] = { 1, 2, 6 };
// Function call
System.out.print(waysToColor(arr, N, K));
}
}
// This code is contributed by sapnasingh4991
Python3
# Python3 program for the above approach
mod = 1000000007
# Recursive function to count the ways
def countWays(colored, count, n):
# Base case
if (count == n):
return 1
# Initialise answer to 0
answer = 0
# Color each uncolored block according
# to the given condition
for i in range(1, n + 1):
# If any block is uncolored
if (colored[i] == 0):
# Check if adjacent blocks
# are colored or not
if (colored[i - 1] == 1 or
colored[i + 1] == 1):
# Color the block
colored[i] = 1
# recursively iterate for
# next uncolored block
answer = ((answer +
countWays(colored,
count + 1,
n)) % mod)
# Uncolored for the next
# recursive call
colored[i] = 0
# Return the final count
return answer
# Function to count the ways to color
# block
def waysToColor( arr, n, k):
# Mark which blocks are colored in
# each recursive step
colored = [0] * (n + 2)
for i in range(k):
colored[arr[i]] = 1
# Function call to count the ways
return countWays(colored, k, n)
# Driver Code
if __name__ == "__main__":
# Number of blocks
N = 6
# Number of colored blocks
K = 3
arr = [ 1, 2, 6 ]
# Function call
print(waysToColor(arr, N, K))
# This code is contributed by chitranayal
C#
// C# program for the above approach
using System;
class GFG{
static int mod = 1000000007;
// Recursive function to count the ways
static int countWays(int []colored,
int count, int n)
{
// Base case
if (count == n)
{
return 1;
}
// Initialise answer to 0
int answer = 0;
// Color each uncolored block according
// to the given condition
for (int i = 1; i < n + 1; i++)
{
// If any block is uncolored
if (colored[i] == 0)
{
// Check if adjacent blocks
// are colored or not
if (colored[i - 1] == 1 ||
colored[i + 1] == 1)
{
// Color the block
colored[i] = 1;
// recursively iterate for
// next uncolored block
answer = (answer +
countWays(colored,
count + 1,
n)) % mod;
// Uncolored for the next
// recursive call
colored[i] = 0;
}
}
}
// Return the final count
return answer;
}
// Function to count the ways to color
// block
static int waysToColor(int []arr,
int n, int k)
{
// Mark which blocks are colored in
// each recursive step
int []colored = new int[n + 2];
for (int i = 0; i < k; i++)
{
colored[arr[i]] = 1;
}
// Function call to count the ways
return countWays(colored, k, n);
}
// Driver Code
public static void Main()
{
// Number of blocks
int N = 6;
// Number of colored blocks
int K = 3;
int []arr = { 1, 2, 6 };
// Function call
Console.Write(waysToColor(arr, N, K));
}
}
// This code is contributed by Code_Mech
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
const int mod = 1000000007;
// Function to count the ways to color
// block
int waysToColor(int arr[], int n, int k)
{
// For storing powers of 2
int powOf2[500] = { 0 };
// For storing binomial coefficient
// values
int c[500][500];
// Calculating binomial coefficient
// using DP
for (int i = 0; i <= n; i++) {
c[i][0] = 1;
for (int j = 1; j <= i; j++) {
c[i][j] = (c[i - 1][j]
+ c[i - 1][j - 1])
% mod;
}
}
powOf2[0] = powOf2[1] = 1;
// Calculating powers of 2
for (int i = 2; i <= n; i++) {
powOf2[i] = powOf2[i - 1] * 2 % mod;
}
int rem = n - k;
arr[k++] = n + 1;
// Sort the indices to calculate
// length of each section
sort(arr, arr + k);
// Initialise answer to 1
int answer = 1;
for (int i = 0; i < k; i++) {
// Find the length of each section
int x = arr[i] - (i - 1 >= 0
? arr[i - 1]
: 0)
- 1;
// Merge this section
answer *= c[rem][x] % mod * (i != 0
&& i != k - 1
? powOf2[x]
: 1)
% mod;
rem -= x;
}
// Return the final count
return answer;
}
// Driver Code
int main()
{
// Number of blocks
int N = 6;
// Number of colored blocks
int K = 3;
int arr[K] = { 1, 2, 6 };
// Function call
cout << waysToColor(arr, N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static int mod = 1000000007;
// Function to count the ways to color
// block
static int waysToColor(int arr[], int n, int k)
{
// For storing powers of 2
int powOf2[] = new int[500];
// For storing binomial coefficient
// values
int [][]c = new int[500][500];
// Calculating binomial coefficient
// using DP
for(int i = 0; i <= n; i++)
{
c[i][0] = 1;
for(int j = 1; j <= i; j++)
{
c[i][j] = (c[i - 1][j] +
c[i - 1][j - 1]) % mod;
}
}
powOf2[0] = powOf2[1] = 1;
// Calculating powers of 2
for(int i = 2; i <= n; i++)
{
powOf2[i] = powOf2[i - 1] * 2 % mod;
}
int rem = n - k;
arr[k++] = n + 1;
// Sort the indices to calculate
// length of each section
Arrays.sort(arr);
// Initialise answer to 1
int answer = 1;
for(int i = 0; i < k; i++)
{
// Find the length of each section
int x = arr[i] - (i - 1 >= 0 ?
arr[i - 1] : 0) - 1;
// Merge this section
answer *= c[rem][x] % mod * (i != 0 &&
i != k - 1 ?
powOf2[x] : 1) %
mod;
rem -= x;
}
// Return the final count
return answer;
}
// Driver Code
public static void main(String[] args)
{
// Number of blocks
int N = 6;
// Number of colored blocks
int K = 3;
int arr[] = { 1, 2, 6 ,0 };
// Function call
System.out.print(waysToColor(arr, N, K));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program for the above approach
mod = 1000000007
# Function to count the ways to color
# block
def waysToColor(arr, n, k):
global mod
# For storing powers of 2
powOf2 = [0 for i in range(500)]
# For storing binomial coefficient
# values
c = [[0 for i in range(500)] for j in range(500)]
# Calculating binomial coefficient
# using DP
for i in range(n + 1):
c[i][0] = 1;
for j in range(1, i + 1):
c[i][j] = (c[i - 1][j]+ c[i - 1][j - 1])% mod;
powOf2[0] = 1
powOf2[1] = 1;
# Calculating powers of 2
for i in range(2, n + 1):
powOf2[i] = (powOf2[i - 1] * 2) % mod;
rem = n - k;
arr[k] = n + 1;
k += 1
# Sort the indices to calculate
# length of each section
arr.sort()
# Initialise answer to 1
answer = 1;
for i in range(k):
x = 0
# Find the length of each section
if i - 1 >= 0:
x = arr[i] - arr[i - 1] -1
else:
x = arr[i] - 1
# Merge this section
answer = answer * (c[rem][x] % mod) * ((powOf2[x] if (i != 0 and i != k - 1) else 1))% mod
rem -= x;
# Return the final count
return answer;
# Driver Code
if __name__=='__main__':
# Number of blocks
N = 6;
# Number of colored blocks
K = 3;
arr = [ 1, 2, 6, 0]
# Function call
print(waysToColor(arr, N, K))
# This code is contributed by rutvik_56
C#
// C# program for the above approach
using System;
class GFG{
static int mod = 1000000007;
// Function to count the ways to color
// block
static int waysToColor(int []arr, int n, int k)
{
// For storing powers of 2
int []powOf2 = new int[500];
// For storing binomial coefficient
// values
int [,]c = new int[500, 500];
// Calculating binomial coefficient
// using DP
for(int i = 0; i <= n; i++)
{
c[i, 0] = 1;
for(int j = 1; j <= i; j++)
{
c[i, j] = (c[i - 1, j] +
c[i - 1, j - 1]) % mod;
}
}
powOf2[0] = powOf2[1] = 1;
// Calculating powers of 2
for(int i = 2; i <= n; i++)
{
powOf2[i] = powOf2[i - 1] * 2 % mod;
}
int rem = n - k;
arr[k++] = n + 1;
// Sort the indices to calculate
// length of each section
Array.Sort(arr);
// Initialise answer to 1
int answer = 1;
for(int i = 0; i < k; i++)
{
// Find the length of each section
int x = arr[i] - (i - 1 >= 0 ?
arr[i - 1] : 0) - 1;
// Merge this section
answer *= c[rem, x] % mod * (i != 0 &&
i != k - 1 ?
powOf2[x] : 1) %
mod;
rem -= x;
}
// Return the readonly count
return answer;
}
// Driver Code
public static void Main(String[] args)
{
// Number of blocks
int N = 6;
// Number of colored blocks
int K = 3;
int []arr = { 1, 2, 6, 0 };
// Function call
Console.Write(waysToColor(arr, N, K));
}
}
// This code is contributed by 29AjayKumar
Javascript
4
时间复杂度: O(N NK )
有效的方法:为了有效地解决这个问题,我们将使用排列和组合的概念。以下是步骤:
1. 如果两个连续着色块之间的块数为 x,则为这组块着色的方法数由下式给出:
ways = 2x-1
2. 给每组未着色的块着色是相互独立的。假设一个部分有x 个块,另一部分有y 个块。要找到合并两个部分时的总组合,由下式给出:
total combinations =
3. 对有色块索引进行排序,找出每个无色块部分的长度,并使用上述公式迭代并找到每两部分的组合。
4. 使用本文中讨论的方法找到二项式系数。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
const int mod = 1000000007;
// Function to count the ways to color
// block
int waysToColor(int arr[], int n, int k)
{
// For storing powers of 2
int powOf2[500] = { 0 };
// For storing binomial coefficient
// values
int c[500][500];
// Calculating binomial coefficient
// using DP
for (int i = 0; i <= n; i++) {
c[i][0] = 1;
for (int j = 1; j <= i; j++) {
c[i][j] = (c[i - 1][j]
+ c[i - 1][j - 1])
% mod;
}
}
powOf2[0] = powOf2[1] = 1;
// Calculating powers of 2
for (int i = 2; i <= n; i++) {
powOf2[i] = powOf2[i - 1] * 2 % mod;
}
int rem = n - k;
arr[k++] = n + 1;
// Sort the indices to calculate
// length of each section
sort(arr, arr + k);
// Initialise answer to 1
int answer = 1;
for (int i = 0; i < k; i++) {
// Find the length of each section
int x = arr[i] - (i - 1 >= 0
? arr[i - 1]
: 0)
- 1;
// Merge this section
answer *= c[rem][x] % mod * (i != 0
&& i != k - 1
? powOf2[x]
: 1)
% mod;
rem -= x;
}
// Return the final count
return answer;
}
// Driver Code
int main()
{
// Number of blocks
int N = 6;
// Number of colored blocks
int K = 3;
int arr[K] = { 1, 2, 6 };
// Function call
cout << waysToColor(arr, N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static int mod = 1000000007;
// Function to count the ways to color
// block
static int waysToColor(int arr[], int n, int k)
{
// For storing powers of 2
int powOf2[] = new int[500];
// For storing binomial coefficient
// values
int [][]c = new int[500][500];
// Calculating binomial coefficient
// using DP
for(int i = 0; i <= n; i++)
{
c[i][0] = 1;
for(int j = 1; j <= i; j++)
{
c[i][j] = (c[i - 1][j] +
c[i - 1][j - 1]) % mod;
}
}
powOf2[0] = powOf2[1] = 1;
// Calculating powers of 2
for(int i = 2; i <= n; i++)
{
powOf2[i] = powOf2[i - 1] * 2 % mod;
}
int rem = n - k;
arr[k++] = n + 1;
// Sort the indices to calculate
// length of each section
Arrays.sort(arr);
// Initialise answer to 1
int answer = 1;
for(int i = 0; i < k; i++)
{
// Find the length of each section
int x = arr[i] - (i - 1 >= 0 ?
arr[i - 1] : 0) - 1;
// Merge this section
answer *= c[rem][x] % mod * (i != 0 &&
i != k - 1 ?
powOf2[x] : 1) %
mod;
rem -= x;
}
// Return the final count
return answer;
}
// Driver Code
public static void main(String[] args)
{
// Number of blocks
int N = 6;
// Number of colored blocks
int K = 3;
int arr[] = { 1, 2, 6 ,0 };
// Function call
System.out.print(waysToColor(arr, N, K));
}
}
// This code is contributed by 29AjayKumar
蟒蛇3
# Python3 program for the above approach
mod = 1000000007
# Function to count the ways to color
# block
def waysToColor(arr, n, k):
global mod
# For storing powers of 2
powOf2 = [0 for i in range(500)]
# For storing binomial coefficient
# values
c = [[0 for i in range(500)] for j in range(500)]
# Calculating binomial coefficient
# using DP
for i in range(n + 1):
c[i][0] = 1;
for j in range(1, i + 1):
c[i][j] = (c[i - 1][j]+ c[i - 1][j - 1])% mod;
powOf2[0] = 1
powOf2[1] = 1;
# Calculating powers of 2
for i in range(2, n + 1):
powOf2[i] = (powOf2[i - 1] * 2) % mod;
rem = n - k;
arr[k] = n + 1;
k += 1
# Sort the indices to calculate
# length of each section
arr.sort()
# Initialise answer to 1
answer = 1;
for i in range(k):
x = 0
# Find the length of each section
if i - 1 >= 0:
x = arr[i] - arr[i - 1] -1
else:
x = arr[i] - 1
# Merge this section
answer = answer * (c[rem][x] % mod) * ((powOf2[x] if (i != 0 and i != k - 1) else 1))% mod
rem -= x;
# Return the final count
return answer;
# Driver Code
if __name__=='__main__':
# Number of blocks
N = 6;
# Number of colored blocks
K = 3;
arr = [ 1, 2, 6, 0]
# Function call
print(waysToColor(arr, N, K))
# This code is contributed by rutvik_56
C#
// C# program for the above approach
using System;
class GFG{
static int mod = 1000000007;
// Function to count the ways to color
// block
static int waysToColor(int []arr, int n, int k)
{
// For storing powers of 2
int []powOf2 = new int[500];
// For storing binomial coefficient
// values
int [,]c = new int[500, 500];
// Calculating binomial coefficient
// using DP
for(int i = 0; i <= n; i++)
{
c[i, 0] = 1;
for(int j = 1; j <= i; j++)
{
c[i, j] = (c[i - 1, j] +
c[i - 1, j - 1]) % mod;
}
}
powOf2[0] = powOf2[1] = 1;
// Calculating powers of 2
for(int i = 2; i <= n; i++)
{
powOf2[i] = powOf2[i - 1] * 2 % mod;
}
int rem = n - k;
arr[k++] = n + 1;
// Sort the indices to calculate
// length of each section
Array.Sort(arr);
// Initialise answer to 1
int answer = 1;
for(int i = 0; i < k; i++)
{
// Find the length of each section
int x = arr[i] - (i - 1 >= 0 ?
arr[i - 1] : 0) - 1;
// Merge this section
answer *= c[rem, x] % mod * (i != 0 &&
i != k - 1 ?
powOf2[x] : 1) %
mod;
rem -= x;
}
// Return the readonly count
return answer;
}
// Driver Code
public static void Main(String[] args)
{
// Number of blocks
int N = 6;
// Number of colored blocks
int K = 3;
int []arr = { 1, 2, 6, 0 };
// Function call
Console.Write(waysToColor(arr, N, K));
}
}
// This code is contributed by 29AjayKumar
Javascript
4
时间复杂度: O(N 2 )