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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

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  Q;
    for (int i=0;iif (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;iif (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"%d",&c[i]);
    for (int i=0;i"%d",&w[i]);
    solve();
    return 0;
}

你可能感兴趣的:(贪心)