📌  相关文章
📜  计算总和等于理想立方的所有三元组

📅  最后修改于: 2021-04-26 18:49:49             🧑  作者: Mango

给定一个由n个整数组成的数组,对所有三元组的总和等于理想立方的总数进行计数,即对于满足a [i] + a [j] + a的任何i,j,k(i 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,这样我们就不必遍历所有k(j P出现了多少次– (a [i] + a [j])在a [j + 1,j + 2,…n]中。
但是,如果我们计算出现在a [j + 1,j + 2,…n]中的数字,例如K,那么这将再次被视为慢速方法,并且肯定会给出TLE。因此,我们必须考虑一种不同的方法。
现在是动态编程。由于所有数字均小于5000,n最多为1000。因此我们可以将DP数组计算为:
dp [i] [K]:= A [i,i + 1,i + 2…n]中K的出现次数

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
?>


输出:

3

时间复杂度: O(N 2 * 24)
辅助空间: O(10 7 )