luoguP1441 【砝码称重】

本文解析了一道经典的砝码称重问题,通过DFS搜索选取砝码组合,并使用DP算法计算可称量的最大不同重量数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

P1441 【砝码称重】

传送门

题目描述

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

输入输出格式

输入格式:

输入文件 weight.in w e i g h t . i n 的第 1 1 行为有两个整数n m m ,用空格分隔

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

输出格式:

输出文件 weight.out w e i g h t . o u t 仅包括 1 1 个整数,为最多能称量出的重量。

输入输出样例

输入样例#1:

3 1 1

1 2 2 2

输出样例#1:

3 3

说明

【样例说明】

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

【数据规模】

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

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

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

对于 100 100 %的数据, n20 n ≤ 20 m4 m ≤ 4 mn m < n ai100 a i ≤ 100

现在小菜鸡爱上了发题解。

于是,今天小菜鸡要挑战一下新高度————发一篇难度为 提高+/省选- 的题解。

废话不多说,拿道题目先看题。

题目大意:从 n n 个砝码中选出nm个,能成量出最多重量。

可以将题目分两个部分:

第一个部分:搜索(dfs)

第二个部分: dp d p 01 01 背包)

AC A C 思路:

1.美好的开始,缺少不了输入
2.用 dfs d f s 解决 n n nm的问题
3.用 dp d p 解决能成量出最多重量的问题

AC A C 代码:

#include<cstdio>//调用      scanf和printf      的库
#include<cstring>//调用      memset      的库
const int mx=205;//定义常量mx
int n,m,maxx=0,ans=0;
int a[mx],b[mx],f[20010];
//定义变量和数组
void dp()//dp(01背包)
{
    memset(f,0,sizeof(f)),f[0]=1;//初始化f,但f[0]=1,否则结果一定为0
    int s=0;//定义一个变量s,做累加
    for(int i=1;i<=n;i++)
    {
        if(b[i]==0)continue;//如果没选,不用再讨论了
        for(int j=maxx;j>=a[i];j--)//从上往下放
        {
            if(f[j-a[i]]==1&&f[j]==0)s++,f[j]=1;//第一次出现,标记并累加
        }
    }
    if(ans<s)ans=s;//更新ans
}
void dfs(int x,int k)//x选k
{
    if(k==m)//选好,进入下一步dp
    {
        dp();
        return ;//返回
    }
    if(x>n)return ;//如果x个超出n个,返回上一层
    dfs(x+1,k);
    b[x]=1;//选中
    dfs(x+1,k+1);//选下一个
    b[x]=0;//还原
}
int main()
{
    memset(b,0,sizeof(b));//初始化b数组为0
    scanf("%d %d",&n,&m),m=n-m;//n选n-m个
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),maxx+=a[i];
    //美好的输入
    dfs(1,0);//跑dfs
    printf("%d",ans);//输出能成量出最多重量
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值