Change-free (codeforces 767E)

题目链接:[http://codeforces.com/contest/767/problem/E]
分析:

肯定要尽可能的不去换硬币,才能使代价最小。
如果至第i天,硬币数量不足以支付,那么应该在第1天至第i天中,选择代价最小的一天让收营员找零。可以发现不管是在哪一天获得硬币,硬币数量都是+100,但是每天的代价都不相同,代价的计算公式为: (100ci%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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值