zoukankan      html  css  js  c++  java
  • C. Insertion Sort DP

    C. Insertion Sort
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Petya is a beginner programmer. He has already mastered the basics of the C++ language and moved on to learning algorithms. The first algorithm he encountered was insertion sort. Petya has already written the code that implements this algorithm and sorts the given integer zero-indexed array a of size n in the non-decreasing order.

    for (int i = 1; i < n; i = i + 1)
    {
    int j = i;
    while (j > 0 && a[j] < a[j - 1])
    {
    swap(a[j], a[j - 1]); // swap elements a[j] and a[j - 1]
    j = j - 1;
    }
    }

    Petya uses this algorithm only for sorting of arrays that are permutations of numbers from 0 to n - 1. He has already chosen the permutation he wants to sort but he first decided to swap some two of its elements. Petya wants to choose these elements in such a way that the number of times the sorting executes function swap, was minimum. Help Petya find out the number of ways in which he can make the swap and fulfill this requirement.

    It is guaranteed that it's always possible to swap two elements of the input permutation in such a way that the number of swap function calls decreases.

    Input

    The first line contains a single integer n (2 ≤ n ≤ 5000) — the length of the permutation. The second line contains n different integers from 0 to n - 1, inclusive — the actual permutation.

    Output

    Print two integers: the minimum number of times the swap function is executed and the number of such pairs (i, j) that swapping the elements of the input permutation with indexes i and j leads to the minimum number of the executions.

    Sample test(s)
    input
    5
    4 0 3 1 2
    output
    3 2
    input
    5
    1 2 3 4 0
    output
    3 4
    Note

    In the first sample the appropriate pairs are (0, 3) and (0, 4).

    In the second sample the appropriate pairs are (0, 4)(1, 4)(2, 4) and (3, 4).


    const int maxn = 5002; int num[maxn]; int sum[maxn][maxn];//sum[i][j] means in range i+1~j there are sum[i][j] numbers are smaller than num[i]; int sum1[maxn][maxn];//sum[i][j] means in range i+1~j there are sum[i][j] numbers are smaller than num[j]; int main() { //freopen("in.txt","r",stdin); int n; while(cin>>n) { repf(i,1,n) scanf("%d",&num[i]); repf(i,1,n) { sum[i][i] = 0; repf(j,i+1,n) { sum[i][j] = sum[i][j-1]; if(num[i] > num[j]) sum[i][j]++; } } repd(j,n,1) { sum1[j][j] = 0; repd(i,j-1,1) { sum1[i][j] = sum1[i+1][j]; if(num[i] < num[j]) sum1[i][j]++; } } int cnt = 0; repf(i,1,n) repf(j,i+1,n) { if(num[i] > num[j]) cnt++; } //cout<<cnt<<endl; int ans1 = cnt; int ans2 = 0; //swap num[i] and num[j] repf(i,1,n) repf(j,i+1,n) { int temp = cnt - sum[i][j-1] + sum1[i+1][j] + (j - 1 - i - sum[i][j-1]) - (j - 1 - i - sum1[i+1][j]); //int temp = cnt + (j-i) - 2*sum[i][j-1] + 2*sum1[i+1][j] - (j-i); if(num[i] < num[j]) temp++; else temp--; ans1 = min(ans1,temp); } repf(i,1,n) repf(j,i+1,n) { int temp = cnt + (j-i) - 2*sum[i][j-1] + 2*sum1[i+1][j] - (j-i); if(num[i] < num[j]) temp++; else temp--; if(temp == ans1) ans2++; } cout<<ans1<<" "<<ans2<<endl; } return 0; }
  • 相关阅读:
    Linux 修改最大线程数
    Openresty+Nginx+Lua+Nginx_http_upstream_check_module 搭建
    SSDB 性能测试
    面向对象:类的成员
    封装,多态,类的约束,super()深入了解
    面向对象:继承
    面向对象:类的空间问题,类之间关系
    面向对象初识
    软件开发规范
    模块(四)包和logging日志
  • 原文地址:https://www.cnblogs.com/DreamHighWithMe/p/3426390.html
Copyright © 2011-2022 走看看