給定數字5、-5,7,-7,12,-12,每個數字個數無限多,從中選擇盡量少的數字,使它們的和為n。
因為對稱性,只需要考慮n>0的情況。
因為存在一對互質的正整數(比如5和7),所以總是存在整數x,y使5x+7y=1,只要能夠產生1,就一定能夠產生任意正整數。因此問題一定有解。
自下而上的更新
缺點是比較暴力,占用空間比較大
a = [5, 7, 12, -5, -7, -12]
b = dict()
for i in a:
b[i] = 1
while 2000 not in b:
c = dict()
for i in b:
for j in a:
k = i + j
if k not in b:
c[k] = b[i] + 1
elif b[i] + 1 < b[k]:
b[k] = b[i] + 1
if len(c) == 0:
break
else:
for i in c:
b[i] = c[i]
ans = sorted(list(b.items()))
ans = [i for i in ans if i[0] >= 0]
with open("test.txt", "w") as f:
for i in ans:
f.write("%d %d\n" % (i[0], i[1]))
最終答案只有兩種選擇:
5,-7,12
-5,7,12
其餘選擇必然不是最優解:選了+5就不能選擇-5,選了5和7,就不能選-12(抵消了),5、7同時選必然不如選擇乙個12。
並且5的個數不會超過7,7的個數不會超過12,否則的話,必然不是最優解。
對於給定的正負數陣列a,首先對a進行從小到大排序,a[0]的個數不能超過a[1],a[1]的個數不能超過a[2],a[2]的個數不能超過a[3]......
a = [5, 7, 12, -5, -7, -12]
def f(m, x):
ans = 0xfffffff
for i in range(12):
for j in range(12):
left = x - m[0] * i - m[1] * j
if left % m[2] == 0:
ans = min(ans, i + j + abs(left // m[2]))
return ans
def solve(x):
return min(f([5, -7, 12], x), f([-5, 7, 12], x))
def output():
with open("f1.txt", 'w') as file:
for i in range(500):
file.write("%d %d\n" % (i, solve(i)))
output()
對於5,7,12三個數字,5的個數肯定不會超過7,7的個數肯定不會超過12。
又因為只有5,-7,12和-7,5,12兩種組合,所以有77+30=107
只需要打錶出0~107,然後其餘部分用12填充即可。
a = [5, 7, 12, -5, -7, -12]
b = dict()
for i in a:
b[i] = 1
limit=43
while limit*3 not in b:
c = dict()
for i in b:
for j in a:
k = i + j
if k not in b:
c[k] = b[i] + 1
elif b[i] + 1 < b[k]:
b[k] = b[i] + 1
if len(c) == 0:
break
else:
for i in c:
b[i] = c[i]
def solve(x):
if x <= limit:
return b[x]
cnt = x // 12
ans = 0xffffff
while x - cnt * 12 < limit:
ans = min(ans, cnt + b[x - cnt * 12])
cnt -= 1
return ans
經過測試,這個問題中的limit至少為43,這是為什麼呢?
給定正整數陣列a[n],從而確定了+a[0],-a[0],+a[1],-a[1]......共2n個整數,從中選擇盡量少的數字,使得它們的和為m。
只需打表處理0~a[0]*a[1]+a[1]*a[2]+a[2]*a[3]+a[3]*a[4]
範圍內的結果,其餘部分必定以最大值a[n-1]填充。
一道演算法題
兩個燒杯,乙個放糖乙個放鹽,用勺子舀一勺糖到鹽,攪拌均勻,然後舀一勺混合 物會放糖的燒杯,問你兩個燒杯哪個雜質多?一樣多吧 對的 為啥?是不是因為 糖和鹽本來就是均勻的 因為,就算不攪拌均,你放一勺過去,那邊放一勺不含雜質的過來,那麼都是一勺雜之 如果攪拌均勻的話也是一樣 小依 21 45 32 也...
一道演算法題
1.上午主要做了對翻譯任務的劃分,下午把 翻譯完畢。2.明天要講的演算法題 對乙個集合,求出其連續元素組成的子集中,和最大的子集 我對這道題的理解是 1 若集合中最小值大於0,意味著所有的都大於0,則最大的子集和,為所有值加起來 2 若集合中最大值小於0,意味著所有的都小於0,則最大的子集和,為集合...
一道演算法題
include using namespace std const int size 5 int max sub array const int a,int n,int m int max matrix const int a size int row,int col,int subsize int...