贪心算法A题

Farmer John has received a noise complaint from his neighbor, Farmer Bob, stating that his cows are making too much noise.
FJ’s N cows (1 <= N <= 10,000) all graze at various locations on a long one-dimensional pasture. The cows are very chatty animals. Every pair of cows simultaneously carries on a conversation (so every cow is simultaneously MOOing at all of the N-1 other cows). When cow i MOOs at cow j, the volume of this MOO must be equal to the distance between i and j, in order for j to be able to hear the MOO at all. Please help FJ compute the total volume of sound being generated by all N*(N-1) simultaneous MOOing sessions.
Input

  • Line 1: N
    Lines 2…N+1: The location of each cow (in the range 0…1,000,000,000).
    Output
    There are five cows at locations 1, 5, 3, 2, and 4.
    Sample Input
    5
    1
    5
    3
    2
    4
    Sample Output
    40
    Hint

INPUT DETAILS:
There are five cows at locations 1, 5, 3, 2, and 4.

OUTPUT DETAILS:
Cow at 1 contributes 1+2+3+4=10, cow at 5 contributes 4+3+2+1=10, cow at 3 contributes 2+1+1+2=6, cow at 2 contributes 1+1+2+3=7, and cow at 4 contributes 3+2+1+1=7. The total volume is (10+10+6+7+7) = 40.

题意

所有奶牛都在同一条直线上,任意两头奶牛都要进行交谈,奶牛A如果想让奶牛B听见它说的话,那么A的音量必须等于AB之间的距离。求所有奶牛一起交谈时的总音量。

输入
n,代表奶牛数量(1 < = n < = 10,000)
随后输入每头奶牛的位置Xi(1 < = i < = n) (0 < = Xi < = 1,000,000,000)

输出
所有奶牛同时交谈的总音量sum

抽象模型

实际上,问题可以转换成求任意两数之差的绝对值之和

举个栗子:

取一般值,为了找规律
    
        x1  x2  x3  x4  x5
        1   2   3   5   8
    x1到其他奶牛的距离
    sx1:1+2+4+7=14
    同样可得x2,x3,x4,x5到其他奶牛的距离
    sx2:1+1+3+6=11
    sx3:2+1+2+5=10
    sx4:4+3+2+3=12
    sx5:7+6+5+3=21
    得
    sum=68
    
    用连线表示相邻的区间是否被计算:
            x1  x2  x3  x4  x5
            1   2   3   5   8
    x1->x2    -   
    x1->x3    -   -   
    x1->x4    -   -   -
    x1->x5    -   -   -   -
    
    x2->x1    -
    x2->x3        -
    x2->x4        -   -
    x2->x5        -   -   -
              
              
    x3->x1    -   -
    x3->x2        -
    x3->x4            -
    x3->x5            -   -
              
    x4->x1    -   -   -
    x4->x2        -   -
    x4->x3            -
    x4->x5                -
    
    x5->x1    -   -   -   -
    x5->x2        -   -   -
    x5->x3            -   -
    x5->x4                -
    
相邻区间计算次数
            1~2 2~3 3~5 5~8
              8  12  12   8
          
          cishu=4*2+3*4+2*6+1*8
          
这其中包含重复计算的区间距离,如x1->x3,x3->x1
如果去掉重复的,即除以2

          cishu’=4*1+3*2+2*3+1*44*1*|2-1|+3*2*|3-2|+2*3*|5-3|+1*4*|8-5|
               =4+6+12+12
               =34
               =68/2
               =sum/2
恰好是sum的一半
想到递推式
half[n]表示对n头牛求任意两个位置之差的绝对值之和
half[n]=(n-i)*i*|x[i]-x[i-1]|
x[0]~x[n-1]存放每头牛的位置
(1<=i<=n-1)

此方法有一个前提

    比如3头牛,位置如下
    1 3 6
    5+2
    5+3
    2+3
    sum=20
    
    若不排序就套公式
    1 6 3
    sum/2=2*1*5+1*2*3=15
    排序后套公式
    1 3 6
    sum/2=2*1*2+1*2*3=10
    
    原因:
    因为牛的位置不同,且在一维直线上,
    为了体现位置关系,模拟现实过程,
    需要将位置排序,再用此规律求解

最佳AC

#include<iostream>
#include<algorithm>
using namespace std;
int n;
long long sum,x[10010];//一定要开longlong,我没开就WA,
//有点奇怪,可能它的int比我想象的小,2^32=42 9496 7296啊
int main(){
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>x[i];
    sort(x,x+n);
    for(int i=1;i<n;i++)
        sum+=(n-i)*i*(x[i]-x[i-1]);
    cout<<sum*2;
}

另一种思路AC
暴力枚举

#include<iostream>
//#include<cmath>不能导入cmath,否则报错,就离谱
//#include<algorithm>
using namespace std;
int n;
long long sum,x[10001];
int main(){
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>x[i];
    //sort(x,x+n);
    for(int i=0;i<n-1;i++)
        for(int j=i+1;j<n;j++)
            sum+=abs(x[i]-x[j]);
    cout<<sum*2;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值