Optmalizacja ilości mnożen

0

Mając n liczb (zbiór A), ktore ze sobą mnożymy:
A={1, 2, 3, 4, ..., n}
i wartosc definiowaną jako wartosc MAX, potrzebuje zapisać najmniejszy możliwy multizbiór iloczynów wartości ze zbioru A taki, zeby był mniejszy od MAX.

Dla danych:

A={1, 2, 3, 4, 5, 6, 7}
MAX=100

interesujący mnie multizbior będzie wyglądał tak:

{6*7*2, 5*4*3} = {84, 60} // chyba, być może da się lepiej
84<100; 60<100

Jak może wyglądac algorytm wyznaczający taki multizbior? Dodam, ze element n zbioru A jest sumą (n-1)+1, czyli te elementy występują w porządku rosnącym, od 1, z różnicą 1. Każdy element ze zbioru A musimy wykorzystać dokładnie jeden raz.
Generalnie chodzi o to, ze mam bardzo dużą liczbe i zamiast mnożyc ją *2 i poźniej *3, to lepiej pomnożyc raz *6 (przykład).

0

Czy dla danych:
A={1, 2, 3, 4, 5, 6, 7}
MAX=50
wynik ma być:
{{7*6},{5*4},{3*2}}
?

0

Tak, to jedna z możliwości. Można też np {(237), (56), (4)}.
W kazdym razie chodzi o to, zeby zamiast mnożyc moją duzą liczbe przez każdy element zbioru A
(23
...7) (6 mnożen)
to moge pomnożyc
(4220
6) (3 mnożenia) <-- Twój wynik

0

42206 - owszem DWA mnożenia, ale 76 to kolejne mnożenie oraz 56 oraz 32 w sumie PIĘĆ mnożeń
czyli dokładnie tyle samo jak w przypadku 7
65432.
Więc nadal nie rozumiem co próbujesz osiągnąć.

0

A jeśli Ci powiem, ze moja duża liczba ma 20mln cyfr? I mnoże to pisemnie? I trzymam w takiej postac (przykład):
23 21 35 45 (każda liczba w osobnej komórce pamięci zadeklarowanej jako bool - dla oszczedności)
Co oznacza liczbe:
25495 (mam nadzieje, że wiesz dlaczego)

  1. 23 21 39 5
  2. 23 24 9 5
  3. 25 4 9 5
  4. 2 5 4 9 5
    i dlatego po każdym mnożeniu mojej dużej liczby musze przeiterowac ten kawałek pamięci w ktorej ją trzymam i przekonwertować to do prawidłowej postaci. I właśnie o to chodzi.
0

I zamierzasz przez zmianę kolejności mnożenia przyspieszyć znalezienie silni?

0

Za dużą liczbe przyjmijmy 12345689
Zbiór A={11, 12, 13, 14} // po wykonaniu kilku mnożen, wiec już sie skrócił

Mnożąc po kolei:
12345678911 - > 29=18 mnożeń + iteracja po wyniku (mnożymy pisamnie - kazda cyfra z każdą)
135802467912 -> 210=20 mnożen + iteracja
1765432082713 -> 211=22 + iteracja
24716049157814 -> 212=24 + iteracja
Co daje łączną liczbe 84 mnożen + 5x iteracja po pamięci z wynikiem

Natomiast:
jako MAX przyjmujemy wartsc maksymalną dla unsigned long long
11121314 -> 3 mnożenia
123456789
24024 -> 45 mnożen + iteracja
Co daje 48 mnożen + jedna iteracja po wyniku

1

@zonkoo22:
Mój algorytm liczenia silnii robi dokładnie to co chcesz osiągnąć. Zamiast robić listę mnożeń, robi drzewo mnożeń, przez co cały proces przyspiesza. Oczywiście nie jest to 100% optymalne, ale jest dużo bliższe niż podejście naiwne.

0

To zwiększ sobie zasięg cyfr:
Użyj systemu np milionarycznego - jedna cyfra jest zapisywana w unsigned i jest mniejsza niż milion;
Więc to : 123456789*11 będzie jednym mnożeniem.

1
unsigned a[]={1110,987654321},b[]={1234,567891011},c[4]={0};
unsigned long long p=0;
p=(unsigned long long)a[1]*b[1];
c[3]=(unsigned)(p%1000000000); p/=1000000000;
p+=(unsigned long long)a[1]*b[0]+(unsigned long long)a[0]*b[1];
c[2]=(unsigned)(p%1000000000); p/=1000000000;
p+=(unsigned long long)a[0]*b[0];
c[1]=(unsigned)(p%1000000000); p/=1000000000;
c[0]=p;
if(c[0]) cout<<c[0]<<setfill('0')<<setw(9)<<c[1];
else cout<<c[1]
cout<<setfill('0')<<setw(9)<<c[2]<<setfill('0')<<setw(9)<<c[3];

1 użytkowników online, w tym zalogowanych: 0, gości: 1