首页 > Web开发 > 详细

「JSOI2010」找零钱的洁癖

时间:2020-01-31 20:12:03      阅读:83      评论:0      收藏:0      [点我收藏+]

「JSOI2010」找零钱的洁癖

传送门
个人感觉很鬼的一道题。。。
首先我们观察到不同的数最多 \(50\) 个,于是考虑爆搜。
但是这样显然不太对啊,状态数太多了。
然后便出现了玄学操作:
\(\text{BFS}\) 的过程中,如果队列中的元素太多了(具体多少我也搞不清)就不搜了,相当于卡时。
但这样又可能会WA,然后就贪心一下就好了???
我反正是不知道为什么可以
可以看这篇博客
参考代码:

#include <algorithm>
#include <cstdio>
#include <queue>
#include <map>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
 
const int _ = 1000002;
 
int aim, n, a[_], ans, now;
map < int, bool > M;
queue < pair < int, int > > Q;
 
int main() {
#ifndef ONLINE_JUDGE
    file("cpp");
#endif
    scanf("%d", &aim);
    while (scanf("%d", &a[++n]) != EOF) ; --n;
    ans = 0x3f3f3f3f;
    sort(a + 1, a + n + 1);
    Q.push(make_pair(0, 0)), M[0] = 1;
    while (!Q.empty()) {
        pair < int, int > x = Q.front(); Q.pop();
        if (x.first == aim) { ans = x.second; break ; }
        for (rg int xx, i = 1; i <= n; ++i) {
            if (x.first < aim && !M[xx = x.first + a[i]]) M[xx] = 1, Q.push(make_pair(xx, x.second + 1));
            if (x.first > aim && !M[xx = x.first - a[i]]) M[xx] = 1, Q.push(make_pair(xx, x.second + 1));
        }
        if (Q.size() > 1000000) break ;
    }
    if (ans != 0x3f3f3f3f) { printf("%d\n", ans); return 0; }
    ans = 0, now = aim;
    for (rg int i = n; i >= 1; --i) {
        if (a[i] == 0) continue ;
        ans += now / a[i];
        now -= now / a[i] * a[i];
    }
    printf("%d\n", ans);
    return 0;
}

「JSOI2010」找零钱的洁癖

原文:https://www.cnblogs.com/zsbzsb/p/12246240.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!