uva 11054 Wine trading in Gergovia

来源:互联网 发布:上海知慧太阳能垃圾箱 编辑:程序博客网 时间:2024/05/16 04:58

原题:
As you may know from the comic Asterix and the Chieftain’s Shield”, Gergovia consists of one street,and every inhabitant of the city is a wine salesman. You wonder how this economy works? Simple enough: everyone buys wine from other inhabitants of the city. Every day each inhabitant decides how much wine he wants to buy or sell. Interestingly, demand and supply is always the same, so that each inhabitant gets what he wants.
There is one problem, however: Transporting wine from one house to another results in work. Since all wines are equally good, the inhabitants of Gergovia don’t care which persons they are doing trade with, they are only interested in selling or buying a speci c amount of wine. They are clever enough to gure out a way of trading so that the overall amount of work needed for transports is minimized.In this problem you are asked to reconstruct the trading during one day in Gergovia. For simplicity
we will assume that the houses are built along a straight line with equal distance between adjacent houses. Transporting one bottle of wine from one house to an adjacent house results in one unit of
work.
Input
The input consists of several test cases. Each test case starts with the number of inhabitants
n (2<=n<=100000). The following line contains n integers ai
(−1000 ≤ a i ≤ 1000). If a i ≥ 0, it means that the inhabitant living in the i-th house wants to buy a i bottles of wine, otherwise if a i < 0,he wants to sell −a i bottles of wine. You may assume that the numbers a i sum up to 0.The last test case is followed by a line containing ‘0’.
Output
For each test case print the minimum amount of work units needed so that every inhabitant has his demand fulfilled. You may assume that this number fits into a signed 64-bit integer (in C/C++ you can use the data type “long long”, in JAVA the data type “long”).
Sample Input
5
5 -4 1 -3 1
6
-1000 -1000 -1000 1000 1000 1000
0
Sample Output
9
9000
大意:
给你n个数,这n个数的总和是0。每个数可以把自己的值分给左右两边的数(两头的除外),现在问你要让所以数都变成0,最少要交换多少个数?

#include <bits/stdc++.h>using namespace std;int main(){    ios::sync_with_stdio(false);    long long n,ans,t,sum;    while(cin>>n,n)    {        sum = ans = 0;        for(int i = 1 ;i <= n ;i++)        {            cin>>t;            if(i!=n)            {                sum+=t;                ans+=abs(sum);            }        }        cout<<ans<<endl;    }    return 0;}

解答:
这种类型的题目一般都是列个方程组,然后找个中位数之类的办法。那么,先列一个方程组。
首先设ai分别为n个给出的数。
设x1表示a1给a2数的大小,如果a1给a2的数是个负数,那么相当于a2给a1了x1个数。
同理,设x2为a2给a3的数的大小,如此下来一直到an-1。
为什么到an-1? 因为an-1是第an-1个数给an个数的大小,不用考虑an。
现在要求Max= abs(x1)+abs(x2)+…+abs(xn-1)
由题目条件可以得出:
a1-x1=0
a2+x1-x2=0
a3+x2-x3=0
……
an-1+xn-2-xn-1=0
an+xn-1=0
上面的方程n个未知数,n个方程,可以解出来。
得到:
x1=a1
x2=a2+a1
x3=a3+a2+a1
……
xn-1=an-1+an-2+….+a1
把上面得到的x1到xn-1带入到Max里面,也就是取绝对值求和就是答案。

0 0
原创粉丝点击