Codeforces 383A Milking cows

Iahub helps his grandfather at the farm. Today he must milk the cows. There are n cows sitting in a row, numbered from 1 to n from left to right. Each cow is either facing to the left or facing to the right. When Iahub milks a cow, all the cows that see the current cow get scared and lose one unit of the quantity of milk that they can give. A cow facing left sees all the cows with lower indices than her index, and a cow facing right sees all the cows with higher indices than her index. A cow that got scared once can get scared again (and lose one more unit of milk). A cow that has been milked once cannot get scared and lose any more milk. You can assume that a cow never loses all the milk she can give (a cow gives an infinitely amount of milk).

Iahub can decide the order in which he milks the cows. But he must milk each cow exactly once. Iahub wants to lose as little milk as possible. Print the minimum amount of milk that is lost.

Input

The first line contains an integer n (1 ≤ n ≤ 200000). The second line contains n integers a1a2, ..., an, where ai is 0 if the cow number i is facing left, and 1 if it is facing right.

Output

Print a single integer, the minimum amount of lost milk.

Please, do not write the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cincout streams or the %I64dspecifier.

Sample test(s)
input
4
0 0 1 0
output
1
input
5
1 0 1 0 1
output
3
Note

In the first sample Iahub milks the cows in the following order: cow 3, cow 4, cow 2, cow 1. When he milks cow 3, cow 4 loses 1 unit of milk. After that, no more milk is lost.


解题思路:贪心算法,本题的贪心做法先从右向左将所有向左看的奶牛挤掉,然后从左向右将所有向右看的奶牛挤掉。
首先显然先挤掉所有方向一致奶牛是最优的,剩下的另一个方向是不需要消耗牛奶的。对某一朝向的所有奶牛消除是有顺序的,假如消除向左看的奶牛,则我们的消除顺序为从右向左消除,这个是可以证明的。
设l[i]表示前i头奶牛向左看的奶牛的头数,r[i]表示前i头奶牛向右看的奶牛的头数,设i,j且i<j,且两头牛均朝左看。
先消除第i头牛然后再消除第j头牛损耗的牛奶数量为:r[i-1]+l[n]-l[i]+r[j-1]+l[n]-l[j]
先消除第j头牛然后再消除第i头牛损耗的牛奶数量为:r[j-1]+l[n]-l[j]+r[k-1]+l[n]-l[k-1]-1,其中减1是因为第j头已经被挤完奶了,后续不会再损耗牛奶了,由上述两个式子我们可以得知先消除j头奶牛再消除第i头奶牛比先消除第i头奶牛再消除第j头奶牛损耗的牛奶要少,因此我们可以得出从右向左的顺序依次消除向左看的奶牛。
因此我们可以得到如下方法:先从右向左消除向左看的奶牛,然后从从左向右消除向右看的奶牛,代码很简单。
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 200010;
int arr[maxn], dp[maxn];
int n;

int main() {

    ll ans = 0;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &arr[i]);
    }
    dp[0] = 0;
    for(int i = 1; i <= n; ++i) {
        dp[i] = dp[i-1] + arr[i];
    }
    for(int i = n; i >= 1; --i) {
        if(arr[i] == 0) {
            ans += dp[i];
        }
    }
    printf("%I64d\n", ans);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值