UVA 11054 Wine trading in Gergovia (贪心+思路)
题目大意:
正数代表的是需要的酒的数量,负数代表的是要卖出的酒的数量,酒店之间都是线性排列的,相邻两个酒店之间的距离都是1。求花最少的费用去交易买卖来满足所有酒店的需求。
思路:
要使得路费最少的话,利用贪心的思想,就让相邻的两个酒店之间进行交易,不管他们是否可以满足各自的要求,只需要先让前一个满足就可以了。这样路费就只是酒*1.
代码:
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define mod 1000000007
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int maxn = 100000 + 5 , inf = 0x3f3f3f3f;
struct wine{
ll cap;
ll pos;
wine(int a= 0,int b = 0){
cap = a;
pos = b;
}
};
wine sell[maxn];
wine buy[maxn];
int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n;
while(scanf("%d",&n)!=EOF&&n){
mem(sell);mem(buy);
ll ans = 0;
int buyLen = 0,sellLen = 0;
for(ll i = 1 ; i <= n ; i++){
ll a;
scanf("%lld",&a);
wine temp(a,i);
if(a>0) sell[sellLen++]=temp;
if(a<0) buy[buyLen++]=temp;
}
int blen = 0 , slen = 0;
while(blen!=buyLen&&slen!=sellLen){
ll maxn = min(sell[slen].cap,-buy[blen].cap);
sell[slen].cap-=maxn;
buy[blen].cap+=maxn;
ans+=(abs(sell[slen].pos-buy[blen].pos))*maxn;
if(sell[slen].cap==0) slen++;
if(buy[blen].cap==0) blen++;
}
printf("%lld\n",ans);
}
}