📌  相关文章
📜  在最多执行K次指定操作后,最大反转范围为1到N

📅  最后修改于: 2021-04-24 18:46:07             🧑  作者: Mango

给定两个整数NK ,任务是在执行最大K次运算后,在前N个自然数序列中找到最大的反转数。在每个操作中,可以交换序列中的任何两个元素。注意:序列中的元素以升序排列,并且序列中没有重复的元素。
例子:

方法:

  1. 由于按升序排列的元素是完美的,即,它的反转为0,而按降序排列的元素是最不理想的,即,它的反转最大。
  2. 因此,其思想是使每个交换操作的序列更接近于降序,以便获得最大的反演。因此,在第一个操作中,我们需要交换最大和最小的元素。同样,在第i个运算中,我们需要将序列中的第i个最大元素与第i个最小元素交换。
  3. 将序列从升序转换为降序所需的交换次数为N / 2 。因此,执行的操作数应小于或等于N / 2
    因此,将K更新为:
  4. 我们需要保持两个变量“ left”“ right”分别代表序列的第i个最小值和第i个最大值。
  5. ‘left’初始化为1并将‘right’初始化为N。
  6. 我们需要执行以下操作,直到K变为0:
    • 开启时,将反转序列号中的“左”“右”交换增加

      因此,将此值添加到答案中。

      • 这是因为当我们交换’left’和’right’时,所有形式的对(right,i)都会对反转产生影响,而且所有形式的对(i,left)都会对反转产生影响,其中left
      • 形式对的总数(右,i) =>右–左,其中左<= i <右
      • 形式对的总数(i,左) =>右–左,其中left
      • 此类对的总数为2 *(右–左)
      • 我们从中减去1,因为在上述计算中该对(右,左)被计数了两次。
    • K“右”的值减小1 ,将“左”的值增大1。
  7. 打印答案的值

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Function which computes the
// maximum number of inversions
int maximum_inversion(int n, int k)
{
    // 'answer' will store the required
    // number of inversions
    int answer = 0;
  
    // We do this because we will
    // never require more than
    // floor(n/2) operations
    k = min(k, n / 2);
  
    // left pointer in the array
    int left = 1;
    // right pointer in the array
    int right = n;
  
    // Doing k operations
    while (k--) {
        // Incrementing ans by number
        // of inversions increase due
        // to this swapping
        answer += 2 * (right - left) - 1;
        left++;
        right--;
    }
    cout << answer << endl;
}
  
// Driver code
int main()
{
    // Input 1
    int N = 5;
    int K = 3;
    maximum_inversion(N, K);
  
    // Input 2
    N = 4;
    K = 1;
    maximum_inversion(N, K);
  
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
  
class GFG{
      
// Function which computes the
// maximum number of inversions
static void maximum_inversion(int n, int k)
{
      
    // 'answer' will store the required
    // number of inversions
    int answer = 0;
  
    // We do this because we will
    // never require more than
    // floor(n/2) operations
    k = Math.min(k, n / 2);
  
    // left pointer in the array
    int left = 1;
      
    // right pointer in the array
    int right = n;
  
    // Doing k operations
    while (k != 0) 
    {
        k--;
          
        // Incrementing ans by number
        // of inversions increase due
        // to this swapping
        answer += 2 * (right - left) - 1;
        left++;
        right--;
    }
    System.out.println(answer);
}
  
// Driver Code
public static void main(String s[])
{
      
    // Input 1
    int N = 5;
    int K = 3;
    maximum_inversion(N, K);
      
    // Input 2
    N = 4;
    K = 1;
    maximum_inversion(N, K);
} 
}
  
// This code is contributed by rutvik_56


Python3
# Python3 program for the above approach
  
# Function which computes the
# maximum number of inversions
def maximum_inversion(n, k):
      
    # 'answer' will store the required
    # number of inversions
    answer = 0;
  
    # We do this because we will
    # never require more than
    # floor(n/2) operations
    k = min(k, n // 2);
  
    # left pointer in the array
    left = 1;
  
    # right pointer in the array
    right = n;
  
    # Doing k operations
    while (k > 0):
        k -= 1;
  
        # Incrementing ans by number
        # of inversions increase due
        # to this swapping
        answer += 2 * (right - left) - 1;
        left += 1;
        right -= 1;
  
    print(answer);
  
# Driver Code
if __name__ == '__main__':
      
    # Input 1
    N = 5;
    K = 3;
    maximum_inversion(N, K);
  
    # Input 2
    N = 4;
    K = 1;
    maximum_inversion(N, K);
  
# This code is contributed by amal kumar choubey


C#
// C# program for the above approach
using System;
  
class GFG{
      
// Function which computes the
// maximum number of inversions
static void maximum_inversion(int n, int k)
{
      
    // 'answer' will store the required
    // number of inversions
    int answer = 0;
  
    // We do this because we will
    // never require more than
    // floor(n/2) operations
    k = Math.Min(k, n / 2);
  
    // left pointer in the array
    int left = 1;
      
    // right pointer in the array
    int right = n;
  
    // Doing k operations
    while (k != 0) 
    {
        k--;
          
        // Incrementing ans by number
        // of inversions increase due
        // to this swapping
        answer += 2 * (right - left) - 1;
        left++;
        right--;
    }
    Console.WriteLine(answer);
}
  
// Driver Code
public static void Main(String []s)
{
      
    // Input 1
    int N = 5;
    int K = 3;
    maximum_inversion(N, K);
      
    // Input 2
    N = 4;
    K = 1;
    maximum_inversion(N, K);
} 
}
  
// This code is contributed by Rohit_ranjan


输出:
10
5

时间复杂度: O(K)
辅助空间: O(1)