法國數學家梅齊亞克在它的《數學組合遊戲》中提出了這樣乙個問題:乙個商人有乙個重量為40磅的砝碼,有一天他不小心將該砝碼摔成了4塊。商人發現每塊砝碼的重量都是整磅數,而且每塊砝碼的重量各不相同,並且發現這四塊砝碼碎片可以在天平上稱出1~40磅之間的任意重量(整磅數)。問這四塊砝碼碎片的重量各是多少?
1、四塊砝碼重量加起來等於40磅
2、每塊砝碼的重量各不相同
3、四塊砝碼碎片可以在天平上稱出1~40磅之間的任意重量(整磅數)
由此可知:問題的求解空間是有限的、可列的,使用窮舉法是一種比較簡便的方法。
演算法描述:
repeat:窮舉組合,其中a,b,c,d互不相等,並且a+b+c+d=40;
if 組合可以在天平上稱出1
~40磅之間的任意重量(整磅數)
then 輸出該組合方式(答案),返回
else 繼續進行窮舉操作
until:窮舉完畢
現在需要解決兩個問題:
一、如何窮舉組合,a,b,c,d互不相等,且a+b+c+d=40?
對於該問題,我們可能很快可以寫出如下的程式:
for
(int i =
1; i <40;
++i)
for(
int j =
1; j <40;
++j)
for(
int k =
1; k <40;
++k)
for(
int s =
1; s <40;
++s)
,為該題的可能解
}
這樣的演算法低效且冗餘。
1、會對很多i,j,k,s相等的情況進行遍歷
2、這裡的組合是不考慮排列方式的組合,即組合與組合其實質是一樣的。
故推薦使用如下優化的演算法:
for
(int i =
1; i <=40;
++i)
for(
int j = i+
1; j <=
40-i;
++j)
for(
int k = j+
1; k <=
40-i-j;
++k)
for(
int s = k+
1; s <=
40-i-j-k;
++s)
if(i+j+k+s ==40)
得到乙個組合,為該題的可能解
該演算法確保內層迴圈搜尋範圍小於外層迴圈搜尋範圍,這樣每次得到的組合方式的4個元素都不會相等,且不會出現「相同組合、不同排列」的情況。
二、如何判斷組合可以在天平上稱出1~40磅之間的任意重量(整磅數)?
如果將其形式化為數學符號,它其實就是要判斷方程:
x 1a
i+x2
bi+x
3ci+
x4di
=wx1
,x2,
x3,x
4∈
x_1a_i+x_2b_i+x_3c_i+x_4d_i=w \ \ \ \ \ x_1,x_2,x_3,x_4\in \
x1ai
+x2
bi+
x3c
i+x
4di
=wx
1,x
2,x
3,x
4∈在w=1,2,3…40時是否都有解。解空間限定在上。
例如:假設有這樣乙個解=使得方程
x 1a
i+x2
bi+x
3ci+
x4di
=1
x_1a_i+x_2b_i+x_3c_i+x_4d_i=1
x1ai
+x2
bi+
x3c
i+x
4di
=1有解,即
1 ×a
i+0×
bi−1
×ci+
1×di
=1⇒a
i+di
=ci+
11×a_i+0×b_i-1×c_i+1×d_i=1\\ \rightarrow a_i+d_i=c_i+1
1×ai+
0×bi
−1×
ci+
1×di
=1⇒
ai+
di=
ci+
1這樣天平的一邊放上碎片ai和di,另一邊放上碎片ci和乙個1磅的砝碼,天平就平衡了,這說明碎片可以稱出1磅的重量。
演算法描述如下:
int
justify
(int i,
int j,
int k,
int s)
是否可以稱出1~40磅之間的任意重量if(
!getweight
(i,j,k,s,weight)
)return0;
//不可以稱出1~40磅之間的任意重量
}return1;
//可以稱出1~40磅之間的任意重量
}
getweight演算法描述如下:
int
getweight
(int i,
int j,
int k,
int s,
int weight)
#include
"stdlib.h"
#include
using
namespace std;
intgetweight
(int i,
int j,
int k,
int s,
int weight)
intjustify
(int i,
int j,
int k,
int s)
是否可以稱出1~40磅之間的任意重量
return0;
//不可以稱出1~40磅之間的任意重量
return1;
//可以稱出1~40磅之間的任意重量
}void
pieces()
,為該題的可能解
cout << i <<
" "<< j <<
" "<< k <<
" "<< s << endl;
}int
main
(int argc,
char
* ar**)
//結果為:1 3 9 27
本題的關鍵在於
1、如何窮舉組合,使得a,b,c,d互不相等,且a+b+c+d=40;
2、如何判斷組合可以在天平上稱出1~40磅之間的任意重量(整磅數)。
解決了這兩個問題,就能得出問題的解。
破碎的砝碼問題
1.問題描述 一天商人不小心把40磅重的砝碼摔成4部分,發現4部分砝碼的重量都是整磅數,而且可以用它們稱出任意1 40之間的整數磅質量,問這四塊砝碼各重多少磅?2.該問題的數學分析 必須有1磅的砝碼,否則39磅的重量無法稱出.有了1磅的砝碼後,再加上乙個3磅的砝碼,可稱出2 4磅的重量.有了1磅和3...
C語言窮舉法解決破碎的砝碼
1.問題描述 一天商人不小心把40磅重的砝碼摔成4部分,發現4部分砝碼的重量都是整磅數,而且可以用它們稱出任意1 40之間的整數磅質量,問這四塊砝碼各重多少磅?2.該問題的數學分析 必須有1磅的砝碼,否則39磅的重量無法稱出.有了1磅的砝碼後,再加上乙個3磅的砝碼,可稱出2 4磅的重量.有了1磅和3...
稱砝碼問題
有一組砝碼,重量互不相等,分別為m1 m2 m3 mn 它們可取的最大數量分別為x1 x2 x3 xn 現要用這些砝碼去稱物體的重量 問能稱出多少種不同的重量。input 測試資料第一行乙個整數n n 10 表示有多種不同的砝碼 第二行n 個整數 中間用空格分隔 m1 m2 m3 mn 分別表示 n...