Codeforces Round #225 (Div. 2) C. Milking cows

C. Milking cows
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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 numberi 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.


给定一队牛,每只牛的头向左或向右,每个看向当前产奶牛的牛产奶量会减一
判断怎么喂可以使减少的奶量最少。
我的思路是先统计头向左的牛个数多还是头向右的个数多,处理个数少的情况可以保证减少的奶量最少
例如
5
1 0 1 0 1
向右的有3只,向左的有2只,就统计从右向左喂头向左的牛即可
因此:
1、若头向右的个数多,统计从左向右喂头向右的牛对应减少的奶量
2、若头向左的个数多,统计从右向左喂头向左的牛对应减少的奶量
刚开始使用暴力的方法做的,发现超时
考虑到可以用数组记录下每只牛左侧头向右的牛的个数  和  每只牛右侧头向左的牛的个数
但是我的代码再第七个测试案例(200000只牛)时会出错
先贴上我的错误代码:
#include <iostream>
#include <string>
#include <vector>
#define rep(i,j,k) for(int i=(j); i<k; ++i)
#define maxn  200010

using namespace std;

int a[maxn],l[maxn],r[maxn];

int main(void){
    int n;
    while(cin >> n){
     int count = 0;
     rep(i,1,n+1){
      cin >> a[i];
      if(a[i]){
       count++;
       l[i+1] = l[i]+1;
      }
      else l[i+1] = l[i];
     }
     
     for(int i=n; i>1; i--){
      if(!a[i])
       r[i-1]=r[i]+1;
      else r[i-1]=r[i];
     }
     
     int lost = 0;
     int icount = 0;
     
     if(count >= (n+1)/2){
      for(int i=n; i>0; i--)
       if(a[i] == 0){
        lost=lost+l[i]+r[i]-icount; 
        icount++;
       }
     }
     
     else
      for(int i=1; i<=n; i++)
       if(a[i]){
        lost=lost+l[i]+r[i]-icount;
        icount++;
       }
     cout << lost << endl;
    }
    return 0;
}
 
尼玛啊!!!!!!!!!!!!
我要一头磕死我自己!!!!大哭发火大哭

lost 的定义改为 long long lost就可以过了!!!!

不过再看别人代码的过程中也发现了自己代码可以改进之处
改进后的代码如下:
#include <iostream>
#include <string>
#include <vector>
#define rep(i,j,k) for(int i=(j); i<k; ++i)
#define maxn  200010

using namespace std;

int a[maxn],l[maxn],r[maxn];

int main(void){
    int n;
    while(cin >> n){
     rep(i,1,n+1){
      cin >> a[i];
      if(a[i])
       l[i+1] = l[i]+1;
      else l[i+1] = l[i];
     }
     
     for(int i=n; i>=1; i--){
      if(!a[i])
       r[i-1]=r[i]+1;
      else r[i-1]=r[i];
     }
     
     long long lost1 = 0;
     long long lost2 = 0;
      
      for(int i=n; i>0; i--)//因为是从右向左找,因此只用找该处前边头向右的 
       if(a[i] == 0)
        lost1 += l[i]; 
     
      for(int i=1; i<=n; i++)//因为是从左向右找,因此只用找给出后边头向左的 
       if(a[i])
        lost2 += r[i];

     cout << ((lost1<lost2)?lost1:lost2) << endl;
    }
    return 0;
}
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值