该题第一映像就没想到过DP,后来看了很多人的博客才发现可以DP。。。
我的思路很简单,用一个数组存入数量k的砝码(k<=n)所组合出的重量,当新加入一个砝码时,查看该砝码能不能与数组中重量组成新的重量,如果能就把新的重量加入到数组中,该数组需要用set或者map进行维护以进行去重。
那么为什么这种方法能过呢?用下面例子为例:
3
1 4 6
当加入砝码1时,数组中的元素为1;
当加入砝码4时,数组中的元素为1、4、3(4 - 1)、5(1 + 4);
当加入砝码6时,数组中的元素为1、4、3(4 - 1)、5(1 + 4)、6、7(1 +6)、10(4 + 6)、9(4 - 1 + 6) 、11(1 + 4 + 6)、2(6 - 4);
那么答案显而易见就是10了(注意:需要检查是否有0的出现,砝码重量不能有0,否则一个全WA)。
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
typedef long long int ll;
ll arr[105];
int main()
{
ll n;
ll ans = 0;
vector<ll> v;
map<ll, int> hash_t;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> arr[i];
for (int j = 1; j <= n; j++)
{
ll k = arr[j];
int len = ans;
if (hash_t.find(k) == hash_t.end())
{
hash_t[k] = ans++;
v.push_back(k);
}
for (int i = 0; i < len; i++)
{
if (hash_t.find(k + v[i]) == hash_t.end())
{
hash_t[k + v[i]] = ans++;
v.push_back(k + v[i]);
}
if (k == v[i]) continue;
else if (hash_t.find(abs(k - v[i])) == hash_t.end())
{
hash_t[abs(k - v[i])] = ans++;
v.push_back(abs(k - v[i]));
}
}
}
//for (int i = 0; i < v.size(); i++)
// cout << v[i] << " ";
//cout << endl;
cout << ans << endl;
// system("pause");
}
附评测结果: