您的位置:首页 > 其它

杭电 HOJ 1394 Minimum Inversion Number 解题报告

2013-02-28 01:16 295 查看
让我们求的是最少的ai>aj数。看到题目是没啥思路。。。在网上搜了一下,有暴力的,有线段树的。

暴力的比较简洁,也很容易弄懂,代码如下:

#include <iostream>
using namespace std;
int s[5001];
int main()
{
int i,j,n,m,a;
while(cin>>n)
{
for(m=i=0;i<n;i++)
for(cin>>s[i],j=0;j<i;j++)
if(s[j]>s[i])
m++;
a=m;
for(i=0;i<n;i++)
if(a>(m=m+n-s[i]*2-1))
a=m;
cout<<a<<endl;
}
}


然后线段树是我自己写的(看过大牛的思路后得到启示。。。)

在输入s[i]后,我们要比较所有先输入的比它大的数字的数量。用线段树保存并更新,查询会快很多。代码如下:

#include <iostream>
using namespace std;
int s[16384],p[5001];
int main()
{
int i,j,n,m,a,t,sta,sum,v;
while(cin>>n)
{
m=0;
memset(s,0,sizeof(s));

t=n-1;
sta=0;
while(t)
{
t>>=1;
sta++;
}
sta=1<<sta;

for(i=0;i<n;i++)
{
cin>>t;
p[i]=t;

t+=sta;
v=t;
while(v)
{
s[v]+=1;
v>>=1;
}

sum=0;
v=sta*2-1;
if(t<v)
{
t++;
for(;v!=t;t>>=1,v>>=1)
if(t&1)
sum-=s[t-1];
m+=sum+s[t];
}
}
a=m;
for(i=0;i<n;i++)
if(a>(m=m+n-p[i]*2-1))
a=m;
cout<<a<<endl;
}
}


代码不怎么好看,见谅。刚接触线段树,用的不是很熟,不过还是很强大的。用了2分的思想,问题的复杂度就会降到logN级别。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: