0 题目来源
1 涉及到的知识点
2 题目
3 思路
经过分析本题可以看出,放入秤上下一个砝码后,能够称出的重量数目,取决于放入上一个砝码后,能够称出的重量数目,即下一个状态取决于上一个状态,这是很明显的动态规划思想。
另外,假设现在天平可以称出重量A,则放入砝码C后,能得到的重量为A+C、|A-C|、C三种情况
因此,我们维护一个集合vec——存放天平当前能够称出的重量(不重复、不存零)。
在每次放入砝码C后,就遍历该集合vec,计算vec[i]+C、|vec[i]-c|,把计算结果以及砝码本身C加入到集合中(需要判断是否重复,若集合中已有,则不加入)
由于在遍历集合vec的过程中,是不需要遍历我们新加入的元素的(加入的砝码只与原来的重量进行运算),因此我们使用一个临时集合对新加入的元素进行存储,待遍历完成后,统一将新加入的元素加入到总集合vec中。
本思路没有采用传统的dp数组思路,之后有空会补充dp数组相关的思路。
4 代码
#include<iostream>#include<vector>#include<cmath>using namespace std;int mp[100001];vector<int> mainvector;int main(){int n;cin >> n;for (int i = 0; i < n; i++){int temp;cin >> temp;vector<int> vec;for (int j = 0; j < mainvector.size(); j++){if (!mp[temp + mainvector[j]]){mp[temp + mainvector[j]] = 1;vec.push_back(temp + mainvector[j]);}if (!mp[abs(temp - mainvector[j])]){mp[abs(temp - mainvector[j])] = 1;vec.push_back(abs(temp - mainvector[j]));}}for (int j = 0; j < vec.size(); j++){if(vec[j] != 0)mainvector.push_back(vec[j]);}if (!mp[temp] && temp != 0){mp[temp] = 1;mainvector.push_back(temp);}}cout << mainvector.size();return 0;}

