zoukankan      html  css  js  c++  java
  • 逆序对 模拟贪心

    题目:

    Inversion逆序数对
    (inversion.cpp/in/out 1s 256M)
    给定N的值,要求找出一个N的全排列,这个全排列中,逆序数有M对。这样的结果会存在多个解,现在请输出字典
    序最小的那个解。例如当输入3 1 时,则1 3 2这个排列有一个逆序对,2 1 3这个排列同样也有一个逆序对。但
    1 3 2这个字典序更小,因而其是正解。
    Input
    每组数据给出N,M。1 <= n <= 50000 and 0 <= m <= 1/2*n*(n-1).
    整个测试以-1 -1代表结束。
    Output
    如题
    Sample Input
    5 9
    7 3
    -1 -1
    Sample Output
    4 5 3 2 1
    1 2 3 4 7 6 5

    可以知道如果有1个数字参加逆序对,则最多0个。
    可以知道如果有2个数字参加逆序对,则最多1个。
    可以知道如果有3个数字参加逆序对,则最多3个。
    可以知道如果有4个数字参加逆序对,则最多6个。
    可以知道如果有5个数字参加逆序对,则最多10个。
    则我们可以利用从N开始倒过来的若干个数字来构成逆序数对,再进行适当的微调就好了

    先预处理,在不断的微调模拟即可。

    code:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 long long n,m,a[50001];
     4 int main()
     5 {
     6     for(int i=1;i<=5000;i++){
     7         a[i]=i*(i-1)/2;
     8          //cout<<"a[i]= "<<a[i]<<endl;   
     9     }
    10     while(cin>>n>>m&&n!=-1)
    11     {
    12         for(int i=1;i<=n;i++)
    13             if(a[i]>m)
    14             {
    15                 //cout<<"i= "<<i<<" a[i]= "<<a[i]<<" n= "<<n<<endl;
    16                 int f=0;
    17                 for(int j=1;j<=n-i;j++)
    18                     cout<<j<<" ";//<<endl;
    19                 cout<<n-(a[i]-m)<<" ";
    20                 for(int j=n;j>=n-i+2;j--)
    21                 if(j==n-a[i]+m)
    22                 {
    23                     f=1;
    24                     continue;
    25                 }
    26                 else cout<<j<<" ";
    27                 if(f)cout<<n-i+1;
    28                 cout<<endl;
    29                 break;
    30             }
    31     }
    32     return 0; 
    33 } 
    34 /*
    35 5 9 
    36 7 3 
    37 -1 -1
    38 */
  • 相关阅读:
    常用dos命令
    反射
    干货|技术小白如何在45分钟内发行通证(TOKEN)并上线交易(附流程代码
    基于以太坊发布属于自己的数字货币(代币)完整版
    基于以太坊实现代币发布
    FTRL的理解
    FM-分解机模型详解
    深度学习总结
    DIN
    git上传新项目
  • 原文地址:https://www.cnblogs.com/nlyzl/p/11679836.html
Copyright © 2011-2022 走看看