蓝桥杯历年试题 砝码称重

看到这个题,自然而然想到用集合set来做,因为set本身就有去重的效果。

#include<bits/stdc++.h>
using namespace std;
int N;
int w;
set<int> s;
int main()
{
	cin >> N;
	for (int i = 1; i <= N; i++)
	{
		cin >> w;
		vector<int> v(s.begin(), s.end());	//这里需要用vector来充当s的大小,因为下一步循环中要确保该次循环size的大小是不变的,循环内部就会增加s中的元素,会陷入死循环 
		for (int i = 0; i < v.size(); i++)	
		{
			s.insert(w + v[i]);
			if( abs(w - v[i])!=0 )	 	//注意取绝对值 
				s.insert(abs(w - v[i]));
		}
		s.insert(w);
	}
	cout << s.size() << endl;	// 集合 s 中装了不同的 “组合重量” 的数量即是答案
	return 0;
}

 这种方法是比较方便的

这个问题主要的两个值就是砝码的个数和能通过加减实现的重量,而前一步可以取到的重量对下一步也有影响,那么又想到用动态规划来解决

设置一个二维数组,第一个维度是指使用了前n个砝码,第二个维度指可以取到的重量,当然并不是所有重量都可以取到,于是设为bool类型,来判断能否取到。能取到的最大重量一定是所有砝码的质量总和,所以循环到其重量之和就可以。

#include<bits/stdc++.h>
using namespace std;

int N;
int a[101];
bool ans[101][1000010];

int main()
{
    int count;
	cin >> N;
	int tol = 0;

	for (int i = 1; i <= N; i++)	
	{
		cin >> a[i];
		all += a[i];	//计算所有砝码总质量,用于循环次数
	}

	for (int i = 1; i <= N; i++)
	{
		for (int j = 1; j <= all; j++)	
			ans[i][j] = ans[i - 1][j];
//首先将i-1所能得到的j继承给i,因为能取到的质量只会在少一个砝码的情况下增加
		for (int j = 1; j <= all; j++) 
		{
			if (ans[i][j] == false)
			{
				if (a[i] == j)		// 新砝码本身的重量
					ans[i][j] = true;
				else if (ans[i-1][j + a[i]] == true)		
					ans[i][j] = true;
				else if (ans[i-1][abs(j - a[i])] == true)	// dp背包思想
					ans[i][j] = true;
			}
		}
	}
	for (int i = 1; i <= all; i++) 
	{
		if (ans[N][i] == true)		// 计数能取到的质量
			count++;
	}
	cout << count << endl;
	return 0;
}

  • 17
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值