HDU 1394

第一次提交的代码果断TLE了,代码如下


#include <stdio.h>
#include <iostream>
#include <string.h>

using namespace std;

#define LEN 5005

int in[LEN], tree[LEN];

int lowbit(int x) {
	return x & (-x);
}

void update(int x) {
	while(x <= LEN) {
		tree[x]++;
		x += lowbit(x);
	}
}

int query(int x) {
	int sum = 0;
	while(x > 0) {
		sum += tree[x];
		x -= lowbit(x);
	}
	return sum;
}

int main() {
	int num;
	while(scanf("%d", &num) != EOF) {
		int i, j;
		for(i = 1; i <= num; i++) {
			scanf("%d", &in[i]);
			in[i]++;
		}
		int min, tmp;
		int index;
		min = 99999;
		for(i = 1; i <= num; i++) {
			index = 0;
			tmp = 0;
			memset(tree, 0, sizeof(tree));
			for(j = i; index < num; index++, j = ((j+1)%num)+1) {
				update(in[j]);
				tmp += j - query(in[j]-1) - 1;
			}
			if(min > tmp) {
				min = tmp;
			}
		}
		printf("%d\n", min);
	}
	return 0;
}


AC代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
 
const int maxn = 5001;
 
int tree[maxn];
int kp[maxn];
 
int n;
 
inline int Lowbit(int x) {
    return x & (-x);
}
 
inline void Update(int x, int v) {
    while (x <= n) {
        tree[x] += v;
        x += Lowbit(x);
    }
}
 
inline int Query(int x) {//返回的是a前边比a小的个数
    int ans = 0;
    while (x > 0) {
        ans += tree[x];
        x -= Lowbit(x);
    }
    return ans;
}
 
int main() {
    while (~scanf("%d", &n)) {
        memset(tree, 0, sizeof(tree));
        int minn = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &kp[i]);
            kp[i]++;
            Update(kp[i], 1);
            minn += i - Query(kp[i]);
        }
 
        int res = minn;
        for (int i = n; i >= 2; i--) {
            //res += kp[i] - 1 - (n - kp[i]);
            //如果以n开头,会增加kp[i] - 1个逆序数,减少n - kp[i]个逆序数
            res += 2 * kp[i] - n - 1;
            //printf("i : %d, mm : %d\n", i, res);
            if (res < minn) {
                minn = res;
            }
        }
        printf("%d\n", minn);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值