Luogu P5020 货币系统

gate

我太菜了,看了标签是背包还不知道是怎么回事qaq

看了下题解,意识到这是个类似素数筛的东西。

感性理解可以发现,原货币系统中能被表示出来的是可以不选的,剩下的就是要选的。所以最小的一定要选,把原货币系统从小到大排序。

枚举原货币系统中的货币a[i],枚举金额j(a[i]+1<j<a[n])

如果j-a[i]可以表示,那么通过a[i],j就也可以表示了。用这种方式判断。

核心代码

for(int i = 1; i <= n; i++) {
    if(vis[a[i]]) continue;
    vis[a[i]] = true;
    ans++;
    for(int j = a[i]+1; j <= a[n]; j++)
        if(vis[j-a[i]]) vis[j] = true;
}

唉——代码好短

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
#include<algorithm>
using namespace std;

const int maxn = 30005;
int t,n,a[maxn],vis[maxn],ans;

void init() {
    ans = 0;
    memset(a,0,sizeof(a));
    memset(vis,0,sizeof(vis));
}

int main() {
    scanf("%d",&t);
    while(t--) {
        init();
        scanf("%d",&n);
        for(int i = 1; i <= n; i++)
            scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        for(int i = 1; i <= n; i++) {
            if(vis[a[i]]) continue;
            vis[a[i]] = true;
            ans++;
            for(int j = a[i]+1; j <= a[n]; j++)
                if(vis[j-a[i]]) vis[j] = true;
        }
        printf("%d
",ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/mogeko/p/11636936.html