[题解] [JSOI2010] 找零钱的洁癖

Posted ztlztl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[题解] [JSOI2010] 找零钱的洁癖相关的知识,希望对你有一定的参考价值。

题面

题解

说实话, 其实我也不知道这题正解是啥
你看着数据范围不像爆搜题
但是爆搜他就是可以过, 我也不知道为啥
奇葩

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <map>
using namespace std;

int X, a[1005], cnt, q[1000005], num[1000005]; 
map<int, bool> mp; 

template < typename T >
inline T read()
{
    T x = 0, w = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * w; 
}

int greedy()
{
    int res = 0, sum = X;
    for(int i = cnt; i; i--)
    {
        res += sum / a[i];
        sum -= sum / a[i] * a[i]; 
    }
    return sum ? 0x3f3f3f3f : res; 
}

int bfs()
{
    int l = 1, r = 0;
    q[++r] = 0, num[r] = 0; 
    while(l <= r && r <= 1000000)
    {
        for(int i = 1; i <= cnt; i++)
        {
            q[++r] = q[l] + 1, num[r] = num[l] > X ? num[l] - a[i] : num[l] + a[i]; 
            if(num[r] == X) return q[r]; 
            if(mp[num[r]] == 1) { r--; continue; }
            mp[num[r]] = 1; 
        }
        l++; 
    }
    return 0x3f3f3f3f; 
}

int main()
{
    X = read <int> ();
    while(scanf("%d", &a[++cnt]) != EOF);
    cnt--; sort(a + 1, a + cnt + 1); 
    if(!X) puts("0");
    else printf("%d
", min(greedy(), bfs())); 
    return 0; 
}

以上是关于[题解] [JSOI2010] 找零钱的洁癖的主要内容,如果未能解决你的问题,请参考以下文章

(原)关于人民币找零钱的问题

java-每位顾客付款后给出找零钱的最佳组合

找零钱的算法实现(Java)

[题解] [JSOI2010] 旅行

[JSOI2010]旅行题解

题解JSOI2010满汉全席