给定一个由 n 个整数组成的数组,计算总和等于完美立方体的所有不同三元组,即对于满足 a[i] + a[j] + a 条件的任何 i, j, k(i < j < k) [j] = X 3其中 X 是任何整数。 3 ≤ n ≤ 1000, 1 ≤ a[i, j, k] ≤ 5000
例子:
Input:
N = 5
2 5 1 20 6
Output:
3
Explanation:
There are only 3 triplets whose total sum is a perfect cube.
Indices Values SUM
0 1 2 2 5 1 8
0 1 3 2 5 20 27
2 3 4 1 20 6 27
Since 8 and 27 are prefect cube of 2 and 3.
天真的方法是通过使用 3 个嵌套循环来迭代所有可能的数字,并检查它们的总和是否是一个完美的立方体。该方法将非常缓慢,因为时间复杂度可以达到 O(n 3 )。
一种有效的方法是使用动态规划和基础数学。根据给定条件,三个正整数中任何一个的和不大于 15000。因此,在 1 到 15000 的范围内只能有 24(15000 1/3 )个立方体。
现在,通过上述信息的帮助,我们可以做得更好,而不是迭代所有三元组。固定前两个索引 i 和 j,这样我们就可以迭代所有 24 个可能的立方体,而不是迭代所有 k(j < k ≤ n),并且对于每个立方体,(假设为 P)检查P出现的次数– (a[i] + a[j])在 a[j+1, j+2, … n] 中。
但是,如果我们计算一个数字 K 在 a[j+1, j+2, … n] 中出现的次数,那么这将再次被视为慢方法,并且肯定会得到 TLE。所以我们必须考虑不同的方法。
现在来到动态规划。由于所有数字都小于 5000 并且 n 最多为 1000。因此我们可以将 DP 数组计算为,
dp[i][K]:= K 在 A[i, i+1, i+2 … n] 中出现的次数
C++
// C++ program to calculate all triplets whose
// sum is perfect cube.
#include
using namespace std;
int dp[1001][15001];
// Function to calculate all occurrence of
// a number in a given range
void computeDpArray(int arr[], int n)
{
for (int i = 0; i < n; ++i) {
for (int j = 1; j <= 15000; ++j) {
// if i == 0
// assign 1 to present state
if (i == 0)
dp[i][j] = (j == arr[i]);
// else add +1 to current state with
// previous state
else
dp[i][j] = dp[i - 1][j] + (arr[i] == j);
}
}
}
// Function to calculate triplets whose sum
// is equal to the pefect cube
int countTripletSum(int arr[], int n)
{
computeDpArray(arr, n);
int ans = 0; // Initialize answer
for (int i = 0; i < n - 2; ++i) {
for (int j = i + 1; j < n - 1; ++j) {
for (int k = 1; k <= 24; ++k) {
int cube = k * k * k;
int rem = cube - (arr[i] + arr[j]);
// count all occurrence of third triplet
// in range from j+1 to n
if (rem > 0)
ans += dp[n - 1][rem] - dp[j][rem];
}
}
}
return ans;
}
// Driver code
int main()
{
int arr[] = { 2, 5, 1, 20, 6 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << countTripletSum(arr, n);
return 0;
}
Java
// JAVA Code for Count all triplets whose
// sum is equal to a perfect cube
import java.util.*;
class GFG {
public static int dp[][];
// Function to calculate all occurrence of
// a number in a given range
public static void computeDpArray(int arr[], int n)
{
for (int i = 0; i < n; ++i) {
for (int j = 1; j <= 15000; ++j) {
// if i == 0
// assign 1 to present state
if (i == 0 && j == arr[i])
dp[i][j] = 1;
else if(i==0)
dp[i][j] = 0;
// else add +1 to current state
// with previous state
else if(arr[i] == j)
dp[i][j] = dp[i - 1][j] + 1;
else
dp[i][j] = dp[i - 1][j];
}
}
}
// Function to calculate triplets whose sum
// is equal to the pefect cube
public static int countTripletSum(int arr[], int n)
{
computeDpArray(arr, n);
int ans = 0; // Initialize answer
for (int i = 0; i < n - 2; ++i) {
for (int j = i + 1; j < n - 1; ++j) {
for (int k = 1; k <= 24; ++k) {
int cube = k * k * k;
int rem = cube - (arr[i] + arr[j]);
// count all occurrence of
// third triplet in range
// from j+1 to n
if (rem > 0)
ans += dp[n - 1][rem] - dp[j][rem];
}
}
}
return ans;
}
/* Driver program to test above function */
public static void main(String[] args)
{
int arr[] = { 2, 5, 1, 20, 6 };
int n = arr.length;
dp = new int[1001][15001];
System.out.println(countTripletSum(arr, n));
}
}
// This code is contributed by Arnav Kr. Mandal.
Python3
# Python 3 program to calculate all
# triplets whose sum is perfect cube.
dp = [[0 for i in range(15001)]
for j in range(1001)]
# Function to calculate all occurrence
# of a number in a given range
def computeDpArray(arr, n):
for i in range(n):
for j in range(1, 15001, 1):
# if i == 0
# assign 1 to present state
if (i == 0):
dp[i][j] = (j == arr[i])
# else add +1 to current state with
# previous state
else:
dp[i][j] = dp[i - 1][j] + (arr[i] == j)
# Function to calculate triplets whose
# sum is equal to the pefect cube
def countTripletSum(arr, n):
computeDpArray(arr, n)
ans = 0 # Initialize answer
for i in range(0, n - 2, 1):
for j in range(i + 1, n - 1, 1):
for k in range(1, 25, 1):
cube = k * k * k
rem = cube - (arr[i] + arr[j])
# count all occurrence of third
# triplet in range from j+1 to n
if (rem > 0):
ans += dp[n - 1][rem] - dp[j][rem]
return ans
# Driver code
if __name__ == '__main__':
arr = [2, 5, 1, 20, 6]
n = len(arr)
print(countTripletSum(arr, n))
# This code is contributed by
# Sahil_Shelangia
C#
// C# Code for Count all triplets whose
// sum is equal to a perfect cube
using System;
class GFG
{
public static int [,]dp;
// Function to calculate all occurrence
// of a number in a given range
public static void computeDpArray(int []arr,
int n)
{
for (int i = 0; i < n; ++i)
{
for (int j = 1; j <= 15000; ++j)
{
// if i == 0
// assign 1 to present state
if (i == 0 && j == arr[i])
dp[i, j] = 1;
else if(i == 0)
dp[i, j] = 0;
// else add +1 to current state
// with previous state
else if(arr[i] == j)
dp[i, j] = dp[i - 1, j] + 1;
else
dp[i, j] = dp[i - 1, j];
}
}
}
// Function to calculate triplets whose
// sum is equal to the pefect cube
public static int countTripletSum(int []arr,
int n)
{
computeDpArray(arr, n);
int ans = 0; // Initialize answer
for (int i = 0; i < n - 2; ++i)
{
for (int j = i + 1; j < n - 1; ++j)
{
for (int k = 1; k <= 24; ++k)
{
int cube = k * k * k;
int rem = cube - (arr[i] + arr[j]);
// count all occurrence of
// third triplet in range
// from j+1 to n
if (rem > 0)
ans += dp[n - 1, rem] -
dp[j, rem];
}
}
}
return ans;
}
// Driver Code
public static void Main()
{
int []arr = { 2, 5, 1, 20, 6 };
int n = arr.Length;
dp = new int[1001, 15001];
Console.Write(countTripletSum(arr, n));
}
}
// This code is contributed
// by 29AjayKumar
PHP
0)
$ans += $dp[$n - 1][$rem] -
$dp[$j][$rem];
}
}
}
return $ans;
}
// Driver code
$arr = array(2, 5, 1, 20, 6);
$n = sizeof($arr);
echo countTripletSum($arr, $n);
// This code is contributed by ita_c
?>
Javascript
输出:
3
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。