from itertools import combinations_with_replacement, combinations def add_mult_chain(n, cost_add, cost_mult): memo = set() mincost = [100000,] def naive_rec(target, s = [1,], cost = 0): if s[-1] == target: tt = cost + cost_add if tt < mincost[0]: mincost[0] = tt #print(s, a) # print(tt) return if cost >= mincost[0]: return adds = [] mults = [] for t in combinations_with_replacement(s[::-1], 2): a = t[0] + t[1] b = t[0] * t[1] adds.append(a) mults.append(b) adds = set(adds) mults = set(mults) if cost_mult< cost_add: for b in mults: if b == target: tt = cost+cost_mult if tt < mincost[0]: mincost[0] = tt return for a in adds: if a == target: tt = cost+cost_add if tt < mincost[0]: mincost[0] = tt return else: for a in adds: if a == target: tt = cost+cost_add if tt < mincost[0]: mincost[0] = tt return for b in mults: if b == target: tt = cost+cost_mult if tt < mincost[0]: mincost[0] = tt return for b in mults: if b not in s and b < target: temp_s = s.copy() temp_s.append(b) if str(sorted(temp_s))+ str(cost + cost_mult) not in memo: memo.add(str(sorted(temp_s))+ str(cost + cost_mult)) naive_rec(target, temp_s, cost + cost_mult) for a in adds: if a not in s and a < target: temp_s = s.copy() temp_s.append(a) if str(sorted(temp_s))+ str(cost+cost_add) not in memo: memo.add(str(sorted(temp_s))+ str(cost + cost_add)) naive_rec(target, temp_s, cost + cost_add) naive_rec(n) return mincost[0] terms = [0,] print(0, end = ', ') for i in range(2, 100): hh = add_mult_chain(i,1,1) print(hh, end = ', ') terms.append(hh)