列表

详情


NC24748. [USACO 2010 Nov G]Cow Photographs

描述

Farmer John wants to take a picture of his entire herd of N (1 <= N <= 100,000) cows conveniently numbered 1..N so he can show off to his friends.
On picture day, the cows run to form a single line in some arbitrary order with position i containing cow c_i (1 <= c_i <= N). Farmer John has his own ideas about how the cows should line up.
FJ thinks cow i may stand only to the left of cow i+1 (for all i, 1 <= i <= N-1) and that cow N may only stand to the left of Cow 1. Of course, no cow will stand to the left of the first (leftmost) cow in the line.
The cows are hungry for the promised post-photo dinner, so Farmer John wants to take the picture as quickly as possible. Cows are not great at following directions, so he will only choose a pair of adjacent cows and have them switch places once per minute. How quickly is Farmer John able to get them into some acceptable order?
Consider a set of 5 cows whose initial lineup looks like this:      Left           Right         3  5  4  2  1 He can first swap the second pair of cows:         3  4  5  2 1 and then swap the rightmost pair:         3  4  5  1  2 to yield an acceptable lineup that required but two minutes of cow swapping.

输入描述

* Line 1: A single integer: N
* Lines 2..N+1: Line i+1 contains the number of the i-th cow in line: c_i

输出描述

* Line 1: The minimum amount of time, in minutes, that it takes Farmer John to get the cows into some appropriate order.

示例1

输入:

5 
3 
5 
4 
2 
1 

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 31ms, 内存消耗: 1636K, 提交时间: 2020-02-26 21:02:42

#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
#define M 100005
using namespace std;
int num[M],P[M],A[M];
void Add(int x)
{
	for(;x<M;x+=lowbit(x))
	num[x]++;
}
int Query(int x)
{
	int res=0;
	for(;x;x-=lowbit(x)) res+=num[x];
	return res;
}
int main()
{
	int n,x;
	long long cnt=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	scanf("%d",&x),P[x]=i,A[i]=x;
	for(int i=1;i<=n;i++)
	{
		Add(A[i]);
		cnt+=i-Query(A[i]);
	 } 
	 long long ans=cnt;
	 for(int i=1;i<n;i++)
	 {
	 	cnt+=n-2*P[i]+1;
	 	ans=min(ans,cnt);
	 }
	 printf("%lld\n",ans);
	 return 0;
}

C++14(g++5.4) 解法, 执行用时: 28ms, 内存消耗: 1976K, 提交时间: 2019-10-19 11:26:52

#include<stdio.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
int n,pos[110000],c[110000],f[110000];
long long ans,te;
inline int ask(int x){
	int ans=0;
	while (x){
		ans+=f[x];
		x-=x&(-x);
	}
	return ans;
}
inline void add(int x){
	while (x<=n){
		f[x]++;
		x+=x&(-x);
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n){
		scanf("%d",&c[i]);
		pos[c[i]]=i;
	}
	fd(i,n,1){
		ans+=ask(c[i]-1);
		add(c[i]);
	}
	te=ans;
	fo(i,1,n-1){
		te+=(n-pos[i])-(pos[i]-1);
		if (te<ans) ans=te;
	}
	printf("%lld\n",ans);
	return 0;
}

上一题