dfs和01背包结合题

深度优先搜索和01背包的综合题,数据不大,很中规中矩

砝码称重

题目描述

现有 n n n 个砝码,重量分别为 a i a_i ai,在去掉 m m m 个砝码后,问最多能称量出多少不同的重量(不包括 0 0 0)。

请注意,砝码只能放在其中一边。

输入格式

1 1 1 行为有两个整数 n n n m m m,用空格分隔。

2 2 2 行有 n n n 个正整数 a 1 , a 2 , a 3 , … , a n a_1, a_2, a_3,\ldots , a_n a1,a2,a3,,an,表示每个砝码的重量。

输出格式

仅包括 1 1 1 个整数,为最多能称量出的重量数量。

样例 #1

样例输入 #1

3 1
1 2 2

样例输出 #1

3

提示

【样例说明】

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

【数据规模】

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

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

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

对于 100 % 100\% 100% 的数据, n ≤ 20 n\leq 20 n20 m ≤ 4 m\leq 4 m4 m < n m < n m<n a i ≤ 100 a_i\leq 100 ai100
题目链接

代码部分:

#include<bits/stdc++.h>//万能头文件   
using namespace std;   
#define N 100005   
int n,m,x,ret=0,ans=0,W,a[N],w[N];//ret为单次dp中的值,ans为总体最优值      
bool f[N];   
void dp() {   
	memset(f,0,sizeof(f));   
	f[0]=1;   
	ret=0;   
	for(int i=1; i<=m; i++)   
		for(int j=W; j>=w[i]; j--) {
			if(f[j-w[i]]&&!f[j]) {
				f[j]=1;   
				ret++;   
			}   
		}   
} //01背包dp部分    
void dfs(int pos,int js) {  
	if(js==m) {  
		dp();  
		ans=max(ans,ret);   
		return;   
	}   
	for(int i=pos+1; i<=n; i++) {   
		w[js+1]=a[i];   
		dfs(i,js+1);   
	}   
}//深搜部分     
int main() {   
	cin>>n>>m;   
	m=n-m;  
	for(int i=1; i<=n; i++) {
		cin>>a[i];   
		W+=a[i];   
	}   
	dfs(0,0);   
	cout<<ans;   
	return 0;   
}   
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值