您的位置:首页 > 其它

luoguP1441 【砝码称重】

2018-04-05 17:26 225 查看

P1441 【砝码称重】

传送门

题目描述

现有nn个砝码,重量分别为a1a1,a2a2,a3a3,……,anan,在去掉mm个砝码后,问最多能称量出多少不同的重量(不包括00)。

输入输出格式

输入格式:

输入文件weight.inweight.in的第11行为有两个整数nn和mm,用空格分隔

第2行有nn个正整数a1a1,a2a2,a3a3,……,anan,表示每个砝码的重量。

输出格式:

输出文件weight.outweight.out仅包括11个整数,为最多能称量出的重量。

输入输出样例

输入样例#1:

33 11

11 22 22

输出样例#1:

33

说明

【样例说明】

在去掉一个重量为22的砝码后,能称量出11,22,33共33种重量。

【数据规模】

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

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

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

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

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

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

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

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

可以将题目分两个部分:

第一个部分:搜索(dfs)

第二个部分:dpdp(0101背包)

ACAC思路:

1.美好的开始,缺少不了输入

2.用dfsdfs解决nn选n−mn−m的问题

3.用dpdp解决能成量出最多重量的问题

上ACAC代码:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: