FZOJ 2166 inversion

2024-09-08 08:58
文章标签 inversion fzoj 2166

本文主要是介绍FZOJ 2166 inversion,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

算是一道模拟题吧,,,此题就逆序数不用归并排序之类的,而是用双层for循环模拟求解,,因为题意中要求任意两个数交换位置,所以只需在双层for循环中模拟两个数交换即可,在模拟的过程中,不需要准确的求出模拟之后的逆序数,只需要考虑逆序数的变化量为多少,最后,求出变化量最小的,用最初的逆序数求得最后结果。。。

其中模拟两个数交换之后逆序数的变化量解法:

如下:

  a,b,c,d,e,f,g,h,i,g,k,l,m.....;   一系列数。

假设我们求交换   d    和    l     的数,其逆序数的变化量。

数列将变为:

  a,b,c,l,e,f,g,h,i,g,k,d,m.....; 

我们先看,在   d    到     l      这一段数中,有多少个比    d     大的数,记为  cnt1   ,那么,将    d    交换之后, 这  cnt1  个数将会各增加1个比其本身小的数,则最终总的逆序数则加  cnt1  ;

我们在看,有多少个比    d    小的数,记为  cnt2 ,  则   相对于   d   来说,最后少了  cnt2  个比    d    小的数, 则最后结果减  cnt2;

同理   对  l   进行一次与   d    相同的操作,则最后的结果变化量则为交换   d     与   l    的逆序数的变化量。


代码如下:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#define INF 0x7fffffff
using namespace std;
int num[1002];
int z[1002][1002];//统计逆序数的变化量。
int main()
{int n;while(~scanf("%d",&n)){memset(z,0,sizeof(z));for(int i=0; i<n; i++){scanf("%d",&num[i]);}int res=0;//求最初的逆序数for(int i=0; i<n; i++){int cnt=0;for(int j=i+1; j<n; j++){if(num[j]<num[i]){res++;//总的逆序数cnt--;}else if(num[j]>num[i])cnt++;z[i][j]=cnt;//统计与第一个交换数比较后的逆序数变化量}}for(int i=n-1; i>0; i--){int cnt=0;for(int j=i-1; j>0; j--){if(num[j]<num[i])cnt++;else if(num[j]>num[i])cnt--;z[j-1][i]+=cnt;//加上与第二个交换数比较后的逆序数变化量}}int m=0;//找到逆序数最小的变化量for(int i=0; i<n; i++)for(int j=i+1; j<n; j++)m=m>z[i][j]?z[i][j]:m;printf("%d\n",res+m);}
}

 

这篇关于FZOJ 2166 inversion的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147670

相关文章

【Hdu】Minimum Inversion Number(逆序,线段树)

利用线段树在nlogn的时间复杂度内求一段数的逆序。 由于给的序列是由0 ~ n -1组成的,求出初始的逆序之后可以递推出移动之后的逆序数。 #include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const in

MapReduce算法 – 反转排序(Order Inversion)

译者注:在刚开始翻译的时候,我将Order Inversion按照字面意思翻译成“反序”或者“倒序”,但是翻译完整篇文章之后,我感觉到,将Order Inversion翻译成反序模式是不恰当的,根据本文的内容,很显然,Inversion并非是将顺序倒排的意思,而是如同Spring的IOC一样,表明的是一种控制权的反转。Spring将对象的实例化责任从业务代码反转给了框架,而在本文的模式中,在map

2166. 子树的大小及深度

代码 #include<bits/stdc++.h>using namespace std;vector<int> a[110];int d[110],s[110];int dfs(int x,int y){int i;s[x]=1;d[x]=d[y]+1;for(i=0;i<a[x].size();i++)if(a[x][i]!=y)s[x]=s[x]+dfs(a[x][i

什么是 Inversion of Control 控制反转

首先解释一下,本篇博客是对博主前两天研究的一篇博客的解释,这里附上这篇博客的链接,大家可以先看一下: Inversion of Control 控制反转 有什么好处 下面咱们进入正题 定义 首先我们看一下,我们需要关注的几个定义: 依赖倒置原则(Dependency Inversion Principle ) a.高层模块不应该依赖于底层模块,二者都应该依赖于抽象。 b.抽象不应该依赖于

HDU 1394 Minimum Inversion Number(线段树求逆序数)

题目地址:HDU 1394 这题可以用线段树来求逆序数。 这题的维护信息为每个数是否已经出现。每次输入后,都从该点的值到n-1进行查询,每次发现出现了一个数,由于是从该数的后面开始找的,这个数肯定是比该数大的。那就是一对逆序数,然后逆序数+1.最后求完所有的逆序数之后,剩下的就可以递推出来了。因为假如目前的第一个数是x,那当把他放到最后面的时候,少的逆序数是本来后面比他小的数的个数。多的逆序数

[Uva 11990] Dynamic Inversion (CDQ分治入门)

Uva - 11990 动态逆序对,求删除一个点之前序列中逆序对的个数 首先倒过来看这个问题,把点先全部删掉 然后从最后一个点开始倒着往数列中加点 求加完这个点逆序对的变化 CDQ分治做法 把删除时间看作 t,下标看作 x,值看作 y 然后对 x排序,对 t偏序,用树状数组维护 y 具体来说就是对于每个点 (t0,x0,y0) (t_0, x_0, y_0) 先统计

【线段树】hdu 1394 Minimum Inversion Number

题意:求Inversion后的最小逆序数 思路:用O(nlogn)复杂度求出最初逆序数后,就可以用O(1)的复杂度分别递推出其他解 线段树功能:update:单点增减 query:区间求和 #include<iostream>#include<algorithm>using namespace std;int sum[10001],x[5001];void pushup(int

hdu1394 Minimum Inversion Number 单点更新

本题虽归于线段树,但实际上只是求逆序数时使用线段树,后面求最小逆序数时并不需要线段树。 首先题目有两个要点: 1.求出原序列的逆序数 2.求出n次移动第一个位置数到最后的逆序数。 对于第一个要点,实际上用暴力也可以解决,当然最好转到线段树的概念上来。 以下我就引用一下别人的话好了。 / * 先以区间[0,9]为根节点建立val都为0的线段树,   再看看

生成式人工智能 - 文本反转(Textual Inversion):一种微调稳定扩散模型的方法

一、简述         大型文本到图像稳定扩散模型已经展示了前所未有的能力,可以使用文本提示合成新场景。这些文本到图像模型提供了通过自然语言指导创作的自由。然而,它们的使用受到用户描述特定或独特场景、艺术创作或新实体产品的能力的限制。很多时候,用户被限制行使她的艺术自由来生成特定独特或新概念的图像。此外,使用新数据集为每个新概念重新训练模型非常困难且成本高昂。         论文《一张图片

HDU - 4911 Inversion

Problem Description bobo has a sequence a 1,a 2,…,a n. He is allowed to swap two adjacent numbers for no more than k times. Find the minimum number of inversions after his swaps. Note: The nu