poj 2838 Cow Sorting 树状数组 两种思路
2017-01-29 10:59
381 查看
题目:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3333 Accepted Submission(s): 1124
Problem Description
Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cows are more likely to damage Sherlock's milking equipment, Sherlock would like to reorder the cows
in line so they are lined up in increasing order of grumpiness. During this process, the places of any two cows (necessarily adjacent) can be interchanged. Since grumpy cows are harder to move, it takes Sherlock a total of X + Y units of time to exchange two
cows whose grumpiness levels are X and Y.
Please help Sherlock calculate the minimal time required to reorder the cows.
Input
Line 1: A single integer: N
Lines 2..N + 1: Each line contains a single integer: line i + 1 describes the grumpiness of cow i.
Output
Line 1: A single line with the minimal time required to reorder the cows in increasing order of grumpiness.
Sample Input
3
2
3
1
Sample Output
7
Hint
Input Details
Three cows are standing in line with respective grumpiness levels 2, 3, and 1.
Output Details
2 3 1 : Initial order.
2 1 3 : After interchanging cows with grumpiness 3 and 1 (time=1+3=4).
1 2 3 : After interchanging cows with grumpiness 1 and 2 (time=2+1=3).
给定n个数,任意交换相邻两个数得不降序列,每次交换代价为两数数值之和,求最小代价。
分析:
按照冒泡排序的方式交换可使得代价最小。每次把最小的冒到最前面去。
思路①对于第i个数a[i],如果它前面有sum_num(i)个数比它大,这些数的和为sum_val(i),则将a[i]交换到最终的位置需要a[i]*sum_num(i)+sum_val(i)
思路②对于第i个数a[i],如果它前面有a个数比它大,后面有b个数比它小,则整个过程中i共参与a+b次交换,i需要的交换次数为 a[i]*(a+b)
代码:
思路①:
思路②:
Cow Sorting
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3333 Accepted Submission(s): 1124
Problem Description
Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cows are more likely to damage Sherlock's milking equipment, Sherlock would like to reorder the cows
in line so they are lined up in increasing order of grumpiness. During this process, the places of any two cows (necessarily adjacent) can be interchanged. Since grumpy cows are harder to move, it takes Sherlock a total of X + Y units of time to exchange two
cows whose grumpiness levels are X and Y.
Please help Sherlock calculate the minimal time required to reorder the cows.
Input
Line 1: A single integer: N
Lines 2..N + 1: Each line contains a single integer: line i + 1 describes the grumpiness of cow i.
Output
Line 1: A single line with the minimal time required to reorder the cows in increasing order of grumpiness.
Sample Input
3
2
3
1
Sample Output
7
Hint
Input Details
Three cows are standing in line with respective grumpiness levels 2, 3, and 1.
Output Details
2 3 1 : Initial order.
2 1 3 : After interchanging cows with grumpiness 3 and 1 (time=1+3=4).
1 2 3 : After interchanging cows with grumpiness 1 and 2 (time=2+1=3).
给定n个数,任意交换相邻两个数得不降序列,每次交换代价为两数数值之和,求最小代价。
分析:
按照冒泡排序的方式交换可使得代价最小。每次把最小的冒到最前面去。
思路①对于第i个数a[i],如果它前面有sum_num(i)个数比它大,这些数的和为sum_val(i),则将a[i]交换到最终的位置需要a[i]*sum_num(i)+sum_val(i)
思路②对于第i个数a[i],如果它前面有a个数比它大,后面有b个数比它小,则整个过程中i共参与a+b次交换,i需要的交换次数为 a[i]*(a+b)
代码:
思路①:
#include<iostream> #include<stdio.h> #include<math.h> #include<algorithm> #include<string.h> using namespace std; #define ll __int64 const int maxn=100009; ll n,a[maxn],c[maxn],d[maxn],ans;//c用来维护数量,d用来维护和 ll get_sum(ll i){//求和 ll s=0; while(i>0){ s+=d[i]; i-=i&(-i); } return s; } ll get_num(ll i){//求数量 ll s=0; while(i>0){ s+=c[i]; i-=i&(-i); } return s; } void add(ll i,ll x){ while(i<=n){ c[i]+=1; d[i]+=x; i+=i&(-i); } } int main(){//46MS 3912K while(~scanf("%I64d",&n)){ ans=0; memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); memset(d,0,sizeof(d)); for(int i=1;i<=n;++i){ scanf("%d",a+i); add(a[i],a[i]); ans+=a[i]*(i-get_num(a[i]));//前面比a[i]大的数的个数 ans+=get_sum(n)-get_sum(a[i]);//比它大的数的和 } printf("%I64d\n",ans); } return 0; }
思路②:
#include<iostream> #include<stdio.h> #include<math.h> #include<algorithm> #include<string.h> using namespace std; #define ll long long const int maxn=100009; ll n,a[maxn],c[maxn],ans;//c用来维护树状数组 ll sum(ll i){//求前缀和 ll s=0; while(i>0){ s+=c[i]; i-=i&(-i); } return s; } void add(ll i,ll x){//结点值更新 while(i<=n){ c[i]+=x; i+=i&(-i); } } int main(){//62MS 3128K 注意全程 long long while(~scanf("%I64d",&n)){ ans=0; memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); for(int i=1;i<=n;++i){//正序建立树状数组,得到前面有多少个比它大 scanf("%d",a+i); add(a[i],1); ans+=a[i]*(i-sum(a[i])); } memset(c,0,sizeof(c)); for(int i=n;i>=1;--i){//逆序建立树状数组,得到后面有多少个比它小 add(a[i],1); ans+=a[i]*sum(a[i]-1); } printf("%I64d\n",ans); } return 0; }
相关文章推荐
- HDU 2838 Cow Sorting(树状数组)
- 杭电2838 Cow Sorting(树状数组)
- HDU 2838 Cow Sorting(树状数组求逆序数)
- HDU - 2838 Cow Sorting (树状数组)
- hud 2838 Cow Sorting 树状数组求逆序数
- HDU 2838 Cow Sorting(树状数组求逆序数)
- HDU 2838 Cow Sorting [树状数组]【数据结构】
- hdu 2838 Cow Sorting(树状数组)
- hdu_2838_Cow Sorting(树状数组求逆序对)
- HDU - 2838 Cow Sorting (树状数组 + 逆序对)
- HDU 2838 Cow Sorting(树状数组)
- hdu 2838 Cow Sorting(树状数组)
- HDOJ 题目2838 Cow Sorting(树状数组逆序对)
- HDU 2838 Cow Sorting(树状数组)
- HDU 2838 Cow Sorting(树状数组-水题)
- hdu 2838 Cow Sorting(树状数组)
- 【POJ 3321】【dfs序(讲解)+(树状数组或者线段树)】Apple Tree【给你一颗树,最初每个节点上都有一个苹果,有两种操作单点修改和查询子树的苹果个数】
- hdu 2838 Cow Sorting(树状数组)
- poj1195 Mobile phones 二维线段树和二维树状数组两种做法 树套树
- hdu 2838 Cow Sorting (树状数组)