• P1441 砝码称重(搜索+队列dp)


    题目链接:传送门

    题目大意:

    给你n个砝码ai,从中去掉m个后求最多的砝码可表示的重量。

    n≤20,m≤4,m<n,ai≤100。

    思路:

    用dfs搜掉m个砝码,然后用队列dp跑出答案,维护答案。

    时间复杂度是O(Cnm * na)。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int N, M, sum;
    int a[25];
    bool vis[25];
    bool f[2005];
    
    int ans;
    
    void dp()
    {
        queue <int> Q;
        Q.push(0);
        for (int i = 0; i < N; i++) if (!vis[i]) {
            int len = Q.size();
            while (len--) {
                int cur = Q.front(); Q.pop();
                int nxt = cur + a[i];
                if (!f[nxt]) {
                    f[nxt] = true;
                    Q.push(nxt);
                }
                Q.push(cur);
            }
        }
        int cnt = 0;
        for (int i = 1; i <= sum; i++) {
            if (f[i]) {
                cnt++;
                f[i] = false;
            }
        }
        ans = max(cnt, ans);
    }
    
    void dfs(int dep, int cur)
    {
        if (dep == M) {
            dp();
        }
        for (int i = cur; i < N; i++) {
            if (!vis[i]) {
                vis[i] = true;
                sum -= a[i];
                dfs(dep+1, i+1);
                sum += a[i];
                vis[i] = false;
            }
        }
    }
    
    void init()
    {
        cin >> N >> M;
        sum = 0;
        ans = 0;
        memset(f, false, sizeof f);
        memset(vis, false, sizeof vis);
        for (int i = 0; i < N; i++) {
            scanf("%d", a+i);
            sum += a[i];
        }
        sort(a, a+N);
    }
    
    int main()
    {
        init();
        dfs(0, 0);
        cout << ans << endl;
        return 0;
    }
    View Code
  • 相关阅读:
    linux命令之free篇
    linux操作之逻辑分区与交换分区篇
    linux之软连接,硬连接篇
    Linux之磁盘分区篇
    Linux命令之vi篇
    JVM总结-垃圾回收算法
    JVM总结-字节码
    JVM总结-java对象的内存布局
    JVM-synchronized怎么实现的?
    JVM总结-invokedynamic
  • 原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/9795204.html
Copyright © 2020-2023  润新知