给定三个正整数N 、 L和R 。任务是找到形成大小为N的数组的方法数,其中每个元素都位于[L, R]范围内,使得数组中所有元素的总和可以被2整除。
例子:
Input: N = 2, L = 1, R = 3
Output: 5
Possible arrays having sum of all elements divisible by 2 are
[1, 1], [2, 2], [1, 3], [3, 1] and [3, 3]
Input: N = 3, L = 2, R = 2
Output: 1
方法:这个想法是找到分别位于 L 和 R 之间的余数为 0 和 1 模 2 的数字的计数。这个计数可以计算如下:
We need to count numbers between range having remainder 1 modulo 2
F = First number in range of required type
L = Last number in range of required type
Count = (L – F) / 2
cnt0, and cnt1 represents Count of numbers between range of each type.
然后,使用动态规划我们可以解决这个问题。令dp[i][j]表示前 i 个数模 2 之和等于 j 的方式数。假设我们需要计算dp[i][0],那么它将有如下递推关系: dp[i][0] = (cnt0 * dp[i – 1][0] + cnt1 * dp[i – 1 ][1]) 。第一项表示到达 (i – 1) 的总和为 0 的路数,因此我们可以将 cnt0 数字放在第i个位置,使得总和仍然保持为 0。 第二项表示到达 (i – 1) 的路数求和余数为 1,因此我们可以将 cnt1 数字放在第i个位置,使求和余数变为 0。类似地,我们可以计算 dp[i][1]。
最终答案将由dp[N][0] 表示。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the number of ways to
// form an array of size n such that sum of
// all elements is divisible by 2
int countWays(int n, int l, int r)
{
int tL = l, tR = r;
// Represents first and last numbers
// of each type (modulo 0 and 1)
int L[2] = { 0 }, R[2] = { 0 };
L[l % 2] = l, R[r % 2] = r;
l++, r--;
if (l <= tR && r >= tL)
L[l % 2] = l, R[r % 2] = r;
// Count of numbers of each type between range
int cnt0 = 0, cnt1 = 0;
if (R[0] && L[0])
cnt0 = (R[0] - L[0]) / 2 + 1;
if (R[1] && L[1])
cnt1 = (R[1] - L[1]) / 2 + 1;
int dp[n][2];
// Base Cases
dp[1][0] = cnt0;
dp[1][1] = cnt1;
for (int i = 2; i <= n; i++) {
// Ways to form array whose sum upto
// i numbers modulo 2 is 0
dp[i][0] = (cnt0 * dp[i - 1][0]
+ cnt1 * dp[i - 1][1]);
// Ways to form array whose sum upto
// i numbers modulo 2 is 1
dp[i][1] = (cnt0 * dp[i - 1][1]
+ cnt1 * dp[i - 1][0]);
}
// Return the required count of ways
return dp[n][0];
}
// Driver Code
int main()
{
int n = 2, l = 1, r = 3;
cout << countWays(n, l, r);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Function to return the number of ways to
// form an array of size n such that sum of
// all elements is divisible by 2
static int countWays(int n, int l, int r)
{
int tL = l, tR = r;
// Represents first and last numbers
// of each type (modulo 0 and 1)
int[] L = new int[3];
int[] R = new int[3];
L[l % 2] = l;
R[r % 2] = r;
l++;
r--;
if (l <= tR && r >= tL)
{
L[l % 2] = l;
R[r % 2] = r;
}
// Count of numbers of each type between range
int cnt0 = 0, cnt1 = 0;
if (R[0] > 0 && L[0] > 0)
cnt0 = (R[0] - L[0]) / 2 + 1;
if (R[1] > 0 && L[1] > 0)
cnt1 = (R[1] - L[1]) / 2 + 1;
int[][] dp = new int[n + 1][3];
// Base Cases
dp[1][0] = cnt0;
dp[1][1] = cnt1;
for (int i = 2; i <= n; i++)
{
// Ways to form array whose sum upto
// i numbers modulo 2 is 0
dp[i][0] = (cnt0 * dp[i - 1] [0]
+ cnt1 * dp[i - 1][1]);
// Ways to form array whose sum upto
// i numbers modulo 2 is 1
dp[i][1] = (cnt0 * dp[i - 1][1]
+ cnt1 * dp[i - 1][0]);
}
// Return the required count of ways
return dp[n][0];
}
// Driver Code
public static void main(String[] args)
{
int n = 2, l = 1, r = 3;
System.out.println(countWays(n, l, r));
}
}
// This code is contributed by Code_Mech.
Python3
# Python3 implementation of the approach
# Function to return the number of ways to
# form an array of size n such that sum of
# all elements is divisible by 2
def countWays(n, l, r):
tL, tR = l, r
# Represents first and last numbers
# of each type (modulo 0 and 1)
L = [0 for i in range(2)]
R = [0 for i in range(2)]
L[l % 2] = l
R[r % 2] = r
l += 1
r -= 1
if (l <= tR and r >= tL):
L[l % 2], R[r % 2] = l, r
# Count of numbers of each type
# between range
cnt0, cnt1 = 0, 0
if (R[0] and L[0]):
cnt0 = (R[0] - L[0]) // 2 + 1
if (R[1] and L[1]):
cnt1 = (R[1] - L[1]) // 2 + 1
dp = [[0 for i in range(2)]
for i in range(n + 1)]
# Base Cases
dp[1][0] = cnt0
dp[1][1] = cnt1
for i in range(2, n + 1):
# Ways to form array whose sum
# upto i numbers modulo 2 is 0
dp[i][0] = (cnt0 * dp[i - 1][0] +
cnt1 * dp[i - 1][1])
# Ways to form array whose sum upto
# i numbers modulo 2 is 1
dp[i][1] = (cnt0 * dp[i - 1][1] +
cnt1 * dp[i - 1][0])
# Return the required count of ways
return dp[n][0]
# Driver Code
n, l, r = 2, 1, 3
print(countWays(n, l, r))
# This code is contributed
# by Mohit Kumar
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to return the number of ways to
// form an array of size n such that sum of
// all elements is divisible by 2
static int countWays(int n, int l, int r)
{
int tL = l, tR = r;
// Represents first and last numbers
// of each type (modulo 0 and 1)
int[] L = new int[3];
int[] R = new int[3];
L[l % 2] = l;
R[r % 2] = r;
l++;
r--;
if (l <= tR && r >= tL)
{
L[l % 2] = l;
R[r % 2] = r;
}
// Count of numbers of each type between range
int cnt0 = 0, cnt1 = 0;
if (R[0] > 0 && L[0] > 0)
cnt0 = (R[0] - L[0]) / 2 + 1;
if (R[1] > 0 && L[1] > 0)
cnt1 = (R[1] - L[1]) / 2 + 1;
int[,] dp=new int[n + 1, 3];
// Base Cases
dp[1, 0] = cnt0;
dp[1, 1] = cnt1;
for (int i = 2; i <= n; i++)
{
// Ways to form array whose sum upto
// i numbers modulo 2 is 0
dp[i, 0] = (cnt0 * dp[i - 1, 0]
+ cnt1 * dp[i - 1, 1]);
// Ways to form array whose sum upto
// i numbers modulo 2 is 1
dp[i, 1] = (cnt0 * dp[i - 1, 1]
+ cnt1 * dp[i - 1, 0]);
}
// Return the required count of ways
return dp[n, 0];
}
// Driver Code
static void Main()
{
int n = 2, l = 1, r = 3;
Console.WriteLine(countWays(n, l, r));
}
}
// This code is contributed by mits
PHP
= $tL)
{
$L[$l % 2] = $l;
$R[$r % 2] = $r;
}
// Count of numbers of each type
// between range
$cnt0 = 0;
$cnt1 = 0;
if ($R[0] && $L[0])
$cnt0 = ($R[0] - $L[0]) / 2 + 1;
if ($R[1] && $L[1])
$cnt1 = ($R[1] - $L[1]) / 2 + 1;
$dp = array();
// Base Cases
$dp[1][0] = $cnt0;
$dp[1][1] = $cnt1;
for ($i = 2; $i <= $n; $i++)
{
// Ways to form array whose sum upto
// i numbers modulo 2 is 0
$dp[$i][0] = ($cnt0 * $dp[$i - 1][0] +
$cnt1 * $dp[$i - 1][1]);
// Ways to form array whose sum upto
// i numbers modulo 2 is 1
$dp[$i][1] = ($cnt0 * $dp[$i - 1][1] +
$cnt1 * $dp[$i - 1][0]);
}
// Return the required count of ways
return $dp[$n][0];
}
// Driver Code
$n = 2;
$l = 1;
$r = 3;
echo countWays($n, $l, $r);
// This code is contributed by Ryuga
?>
Javascript
5
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。