zoukankan      html  css  js  c++  java
  • 洛谷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;
    }
    
  • 相关阅读:
    【SDOI2014】数表
    【洛谷P4735】最大异或和
    FFT学习笔记
    【SHOI2008】堵塞的交通
    HDU 1754 I Hate It 线段树
    hdu 1166 敌兵布阵 ( 线段树或者树状数组)
    hdu 5339 Untitled dfs
    The mook jong
    hdu 5363 Key Set 快速幂
    HDU 1983 Kaitou Kid
  • 原文地址:https://www.cnblogs.com/solvit/p/11390034.html
Copyright © 2011-2022 走看看