• 洛谷P1441 砝码称重(搜索,dfs+dp)


    洛谷P1441 砝码称重

    (n) 的范围为 (n le 20)(m) 的范围为 (m le 4)

    暴力遍历每一种砝码去除情况,共有 (n^m) 种情况。

    对于剩余砝码求解可以组合的重量种类数。简单dp求解。复杂度为 (O(n imes n imes m))

    时间复杂度为 (O(n^m imes n imes n imes m)) 。实际复杂度应该比这个小很多,剪枝效果明显。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    
    using namespace std;
    
    const int maxn = 25;
    const int maxm = 2005;
    int n, m, ans, sum;
    int vis[maxn], a[maxn], f[maxm];
    
    void solve()
    {
        for(int i = 0; i <= sum; i++) f[i] = 0;
        f[0] = 1;
        int tot = 0, ret = 0;
        for(int i = 1; i <= n; i++){
            if(vis[i] == 1) continue;
            for(int j = tot; j >= 0; j--){
                if(f[j] == 1 && f[j + a[i]] == 0){
                    ret++; f[j + a[i]] = 1;
                }
            }
            tot += a[i];
        }
        ans = max(ans, ret);
    }
    void dfs(int now, int step)
    {
        if(step == m + 1){
            solve();
            return;
        }
        for(int i = now; i <= n; i++){
            vis[i] = 1;
            dfs(i + 1, step + 1);
            vis[i] = 0;
        }
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        sum = 0;
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            sum += a[i];
        }
        ans = 0;
        dfs(1, 1);
        printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    C#中创建Android项目
    C#中创建Android项目
    在C#中获取当前屏幕的分辨率的方法
    数据库面试
    计算机网络面试
    linux面试
    Java使用递归检索文件个数
    二分查找
    富途证券面经(一面挂)
    Mysql
  • 原文地址:https://www.cnblogs.com/solvit/p/11390034.html
Copyright © 2020-2023  润新知