(1)给出N个指定质量的砝码,和一个重M的物体,请指出称此物体所需要的最少砝码数量?
注:称量方法既可以为砝码加砝码形式,也可以为砝码减砝码形式
参数形式:N(砝码数量) M(物体重量)
M1(砝码1质量)
......
Mn(砝码1质量)
#include <map>
#include <vector>
#include <iostream>
using namespace std;
void fInsert(int weigh, int count, map<int,int> &wMap)
{
if(weigh == 0)
{
return;
}
auto it = wMap.find(weigh);
if(it == wMap.end())
{
wMap.insert(pair<int,int>(weigh,count));
}
else if(count < it->second)
{
it->second = count;
}
}
int main()
{
int m, n;
cin>>n>>m;
vector<int> weightVec;
map<int,int> weighMap;
for(int weight,i=0; i<n; i++)
{
cin>>weight;
weightVec.push_back(weight);
}
for(int i=0; i<weightVec.size(); i++)
{
map<int,int> addWeighMap;
addWeighMap.insert(pair<int,int>(weightVec[i],1));
for(auto iter=weighMap.begin(); iter!=weighMap.end(); iter++)
{
int weigh = iter->first - weightVec[i];
int count = iter->second + 1;
if(weigh < 0)
{
weigh = 0 - weigh;
}
fInsert(weigh, count, addWeighMap);
weigh = iter->first + weightVec[i];
fInsert(weigh, count, addWeighMap);
}
for(auto iter = addWeighMap.begin(); iter != addWeighMap.end(); iter++)
{
fInsert(iter->first, iter->second, weighMap);
}
}
auto it = weighMap.find(m);
if(it != weighMap.end())
{
cout<<"最少需砝码数量:"<<it->second<<endl;
}
else
{
cout<<"使用所给砝码无法称出所给重量物体!"<<endl;
}
}
(2)梅氏砝码问题,其叙述如下:
若有n个砝码,重量分别为M1,M2,……,Mn,且能称出从1到(M1+M2+……+Mn)的所有重量,则再加一个砝码,重量为Mn+1=(M1+M2+……+Mn)*2+1,则这n+1个砝码能称出从1到 (M1+M2+……+Mn+Mn+1)的所有重量。
我们尝试构造这样一个序列。从1开始逐次拓展,使可称重的重量不断向后延伸:
1 1 1 1
1 3 1+3=4 3-1=1+1 1~4
1 3 9 1+3+9=13 9-(1+3)=(1+3)+1 1~13
1 3 9 27 1+3+9+27=40 27-(1+3+9)=(1+3+9)+1 1~40
......
如当前所有砝码重量和为S,则S是这些砝码能称的最大重量。考虑下一个扩展的砝码重量X,那么容易想到,扩展后X-S~X+S都可以称量。考虑节省做法,应该使X-S=S+1,这样可以推得下一个砝码质量。
S+1=X-S ——> X = 2S+1