题目链接:[http://codeforces.com/contest/767/problem/E]
分析:
肯定要尽可能的不去换硬币,才能使代价最小。
如果至第i天,硬币数量不足以支付,那么应该在第1天至第i天中,选择代价最小的一天让收营员找零。可以发现不管是在哪一天获得硬币,硬币数量都是+100,但是每天的代价都不相同,代价的计算公式为:
(100−ci%100)∗wi
(
100
−
c
i
%
100
)
∗
w
i
,将其丢进优先队列中,每次取出最小代价就可以了。
具体实现见代码
AC代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<time.h>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
using namespace std;
const int maxn = 1e5+100;
struct node
{
int w,id;
node (int value = 0, int ID = 0)
{
w = value, id = ID;
}
friend bool operator < (const node &a,const node &b)
{
return a.w>b.w;
}
};
int n,x,c[maxn],w[maxn];
bool f[maxn];
void solve()
{
long long ans = 0;
priority_queue <node> Q;
for (int i=0;i<n;i++)
{
if (c[i] % 100 == 0) continue;
int v = (100-c[i]%100) * w[i];
Q.push(node(v,i));
while (x < c[i]%100)
{
ans += Q.top().w;
f[Q.top().id] = true;
x += 100;
Q.pop();
}
x -= c[i]%100;
}
printf("%I64d\n",ans);
for (int i=0;i<n;i++)
{
if (f[i])
printf("%d 0\n",c[i]/100+1);
else
printf("%d %d\n",c[i]/100,c[i]%100);
}
return;
}
int main()
{
scanf("%d %d",&n,&x);
for (int i=0;i<n;i++) scanf("%d",&c[i]);
for (int i=0;i<n;i++) scanf("%d",&w[i]);
solve();
return 0;
}