货币系统(完全背包)

货币系统

https://ac.nowcoder.com/acm/problem/21228


题目:

给你n个数的正整数集合。让你挑选最少的数,使两个集合等价。集合等价,即两个集合能表示的数的集合相同。


做法:

由于给的都是正整数。题目就是让我们求给定的n个数中,哪些数是不必要的。
所谓不必要,即某个数能被集合中的其他数表示。我们将集合a[]排序。若a[i]能被前i-1个数中的某个子集表示,则这个数就是不必要的。
想到这,不难发现这就是个完全背包。
做完全背包时,考虑到第i个数时,此时dp[]数组保存的恰是前i-1个数能表示的所有数。我们check一下此时dp[a[i]]的值。若为1说明a[i]容量的背包能被前i-1个数装满。即不必要


代码:

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
#define debug(a) cout << #a ": " << a << endl
using namespace std;
typedef long long ll;
const int N = 25000 + 7;
int a[N], dp[N];
int main(void){
    IOS;
    int T; cin >> T;
    while (T--){
        memset(dp, 0, sizeof dp);
        int n; cin >> n;
        for (int i = 1; i <= n; ++i) cin >> a[i];
        sort(a+1, a+n+1);
        int mx = a[n];
        dp[0] = 1;
        int ans = n;
        for (int i = 1; i <= n; ++i){
            if (dp[a[i]]){
                ans--; continue;
            }
            for (int j = 1; j <= mx; ++j){
                if (j >= a[i]){
                    dp[j] |= dp[j-a[i]];
                }
            }
        }
        cout << ans << endl;
    }

    return 0;
}
全部评论

相关推荐

点赞 评论 收藏
分享
03-04 22:29
已编辑
门头沟学院 Web前端
家人们上上周我花了一天时间写了一下简历,然后投出去试试水看看有没有反应,结果投出去6份,有一个北京某1000人以上规模公司的笔试邀请和南京某20人规模的公司的面试。明天中午就要面试了,说要做一个ppt讲述一下项目经验,我有点摸不着头脑,不知道怎么写,我想写第一个管理系统的项目,但是感觉没啥亮点,也不知道要怎么描述介绍。大家可以帮我看一下简历怎么改吗?顺便能不能指导一下ppt要怎么写好紧张啊,第一次面试。
EvanderLiam:前端的技术栈不懂,所以不知道你项目和技术栈写的怎么样。但是简历别的可以说一下,首先,自我介绍没有用,全部删掉;然后,如果学历不占优可以往下移,移到最下面(虽然可能没啥帮助);再然后,技术栈可以用粗体标注关键字,让面试官可以知道哪些可以有重点的问;最后就是项目的工作内容,不要写你做了什么,不要为了用而用,而是遇到了什么场景,使用了什么技术,解决了什么问题,最后效果如何(最好有量化的指标),这是大概的思路。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务