• LUOGU P1441 砝码称重


    题目描述

    现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0)。

    输入输出格式

    输入格式:
    输入文件weight.in的第1行为有两个整数n和m,用空格分隔

    第2行有n个正整数a1,a2,a3,……,an,表示每个砝码的重量。

    输出格式:
    输出文件weight.out仅包括1个整数,为最多能称量出的重量。

    输入输出样例

    输入样例#1:
    3 1
    1 2 2
    输出样例#1:
    3
    说明

    【样例说明】

    在去掉一个重量为2的砝码后,能称量出1,2,3共3种重量。

    【数据规模】

    对于20%的数据,m=0;

    对于50%的数据,m≤1;

    对于50%的数据,n≤10;

    对于100%的数据,n≤20,m≤4,m<n,ai≤100。

    解题思路

    搜索+背包,还是比较容易的,不需要什么剪枝,记一个pre,每次从pre+1循环即可。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    
    using namespace std;
    const int N = 25;
    
    int n,m,a[N],ans,sum;
    bool vis[N],dp[2005];
    
    inline void solve(){
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        for(register int i=1;i<=n;i++){
            if(vis[i]) continue;
            for(register int j=sum;j>=a[i];j--)
                dp[j]|=dp[j-a[i]];
        }
        int ret=0;
        for(register int i=1;i<=sum;i++) 
            if(dp[i]) ret++;
        ans=max(ans,ret); 
    }
    
    inline void dfs(int x,int pre){
        if(x==m+1) {solve();return;}
        for(register int i=pre+1;i<=n;i++){
            if(vis[i]) continue;
            vis[i]=1;
            dfs(x+1,i);
            vis[i]=0;
        }
    }
    
    int main(){
    //  freopen("data.txt","r",stdin);
        scanf("%d%d",&n,&m);
        for(register int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i];
        dfs(1,0);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    PowerShell 学习(一):运算符
    Create word clouds with Wordle
    淘宝惊现“同店购”?
    “二叉查找树”学习
    云计算软件之——OpenNebula
    "栈"应用——求解迷宫
    "队列"学习
    “串”学习——三种表示方法
    尖端技术104之计算机技术的未来
    “二叉树”——链表表示
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676904.html
Copyright © 2020-2023  润新知