BAOWUNOJ平分石头

题目

题目描述

给定 N 块石头与目标数值 M,每块石头只能选或者不选,从中挑选若干块石头,使得选出石头的总质量最接近 M,输出这个总质量。
输入格式第一行两个整数 N、M;
接下来 N 行,每行一个整数,表示单块石头的质量。输出格式输出满足条件的石头总质量。

数据范围

(0 < N < 200)
(0 < M < 10000)
单块石头质量:不超过 300 的正整数
所有石头总重量上限:(200 \times 300 = 60000)

时空限制

时间限制:1 秒
内存限制:512 MB
样例输入5 10
1
2
3
4
5
样例输出10
样例解释选取 1、2、3、4 四块石头,总和恰好等于 10,与目标差值为 0,为最优解。

思路

根据题意可以看出这道题是一个典型的01背包问题
1.可以用bool数组dp来确定能否达到这个质量,并且定义一个变量sum来确定最大值,sum就是所有石头的和
2.初始化dp[0]=true,因为0是可以被确定的
3.开始01背包,如果确定dp[j-a[i]]==true,就把dp[j]=true
4.最后遍历0到sum这个区间,如果i确定就看是否小于我们的mi,如果小于ans=i

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,ans,mi=1e9;
int a[205],sum=0;
bool dp[60005]; 
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum+=a[i];//求总和
	}
	dp[0]=true;//初始化
	for(int i=1;i<=n;i++){
		for(int j=sum;j>=a[i];j--){
			if(dp[j-a[i]]){//如果可以达到那么dp[j]=true
				dp[j]=true;
			}
		}
	}
	for(int i=0;i<=sum;i++){//遍历整个区间
		if(dp[i]){//如果可以达到就看是否小于最小值
			int s=abs(i-m);//求差
			if(s<mi){
				mi=s;
				ans=i;
			} 
		}
	}
	cout<<ans;
	return 0;
} 

这道题是一个典型的01背包模板题,很适合新手练练手感

点点赞吧QWQ

posted @ 2026-07-25 15:30  陈晨2011  阅读(7)  评论(0)    收藏  举报