I'm having a very hard time trying to figure out how to solve this problem efficiently. Let me describe how it goes:
"A hard working mom bought several fruits with different nutritional values for her 3 kids, Amelia, Jessica and Bruno. Both girls are overweight, and they are very vicious and always leave poor Bruno with nothing, so their mother decided to share the food in the following manner:
Amelia being the heaviest one gets the most amount of Nutritional Value
Jessica gets an amount equal or less than Amelia
Bruno gets an amount equal or less than Jessica, but you need to find a way to give him the highest possible nutritional value while respecting the rule ( A >= J >= B )"
Note: The original problem is described differently but the idea is the same, I don't want my classmates to find this post when they google for help hehe.
One of the test cases given by my teacher is the following:
The fruit list has the following values { 4, 2, 1, 8, 11, 5, 1}
Input:
7 -----> Number of Fruits
4 2 1 8 11 5 1 ----> Fruits Nutritional Values
Output:
1 11 ----> One fruit, their nutritional values sum for Amelia
5 ----> Position of the fruit in the list
3 11 ----> Three fruits, their nutritional values sum for Jessica
1 2 6 ----> Position of the fruits in the list
3 10 ----> Three fruits, their nutritional values sum for Bruno
3 4 7 ----> Position of the fruits in the list
Note: I am aware that there are several ways of diving the fruits among the kids, but it doesn't really matter as long as it follows the rule A >= J >= B.
At first I made an algorithm that generated all the subsets, each one had their sums, and the positions that were in use. That method was quickly discarded because the list of fruits can have up to 50 fruits, and the subset algorithm is O(2^n). I ran out of memory.
The second idea that I have is to use Dynamic Programming. In the columns header I would have the positions of the Fruit's List, in the row header the same, it's kind of hard to explain with letters so I'll ahead an do the table for the previous example { 4, 2, 1, 8, 11, 5, 1}.
00 01 02 03 04 05 06 07
00
01
02
03
04
05
06
07
Each time we advance to the row below we add the positions 1,2,3,...,7
00 01 02 03 04 05 06 07
00 00 <---No positions in use
01 04 <---RowPosition 1 + Column Position(Column 0) (4+0)
02 06 <---RowPosition 1 + RowPosition 2 + Column Position (4+2+0)
03 07 <---RP(1) + RP(2) + RP(3) + CP(0) (4+2+1+0)
04 15 <--- (4+2+1+8+0)
05 26
06 31
07 32 <--- (4+2+1+8+11+5+1+0)
Now that you know how it goes lets add the first row
00 01 02 03 04 05 06 07
00 00 04 02 01 08 11 05 01 <-- Sum of RP + CP
01 04 00 06 05 12 15 09 05 <-- Sum of RP(0..1) + CP
02 06
03 07
04 15
05 26
06 31
07 32
I put the 00 because the 1st position is already in use. The completed table would look like this.
00 01 02 03 04 05 06 07
00 00 04 02 01 08 11 05 01
01 04 00 06 05 12 15 09 05
02 06 00 00 07 14 17 11 07
03 07 00 00 00 15 18 12 08
04 15 00 00 00 00 26 20 16
05 26 00 00 00 00 00 31 27
06 31 00 00 00 00 00 00 32
07 32 00 00 00 00 00 00 00
Now that we have the table. I divide the sum of the Nutritional Values by the amount of kids, 32/3 = 10.6667, the ceiling would be 11. I try to check for 11, if it's in the table, I choose it and mark the position of the row and columns of the tables as used, then I would try to check for 11 again, if it's in the table I choose it otherwise look the 10, or 9, etc until I find it. Afterwards I would mark the respective positions as used then sum the unused positions to get Bruno's fruits.
I know that there has to be better way to do this because I found a flaw in my method, the table only has the sum of a few subsets. So maybe that will be detrimental in a few test cases. Maybe a 3D Memoization Cube?, I think it would consume too much memory, and I have a limit too 256MB.
Wow, I didn't realize I typed this much x.X. I hope I don't get a lot of tl; dr. Any help / guide would be greatly appreciated :D
EDIT: I made the code that generates the table in case anyone wants to try it out.
static void TableGen(int[] Fruits)
{
int n = Fruits.Length + 1;
int[,] memo = new int[n, n];
for (int i = 1; i < n; i++)
{
memo[0, i] = Fruits[i - 1];
memo[i, 0] = memo[i - 1, 0] + Fruits[i - 1];
for (int j = i + 1; j < n; j++)
memo[i, j] = memo[i, 0] + Fruits[j - 1];
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
Console.Write("{0:00} ", memo[i, j]);
Console.WriteLine();
}
}
A slightly computationally intensive way would be to assign the fruit in a round robin way, starting with the highest nutritional value for amelia.
From there, progressively loop through the fruit from lowest nutritional value held by amelia, and try each combination of either (a) giving the fruit to jessica, or (b) swapping the fruit with one held by jessica, while still satisfying the rule.
Then apply the same method to jessica and bruno. Repeat these 2 loops until no more swaps or gives are possible.
Slightly trickier, but potentially faster, would be to simultaneously give/swap to jess/bruno. For each 2 pieces of fruit that A holds, you would have 4 options to try, with more if you at the same time try and balance J & B.
For a faster algorithm, you could try asking at the mathematics stack exchange site, as this is very much a set-theory problem.
for(i = 0; i < count; i++)
{
currentFruit=Fruits.Max();
if(Amelia.Sum() + currentFruit < Jessica.Sum() + currentFruit)
{
Amelia.Add(currentFruit);
Fruits.Remove(currentFruit);
continue;
}
if(Jessica.Sum() + currentFruit < Bruno.Sum() + currentFruit)
{
Jessica.Add(currentFruit);
Fruits.Remove(currentFruit);
continue;
}
Bruno.Add(currentFruit);
Fruits.Remove(currentFruit);
}
This works for fruits with relatively similar values. If you add a fruit whose value is greater than all other fruits combined (which I did once by accident) it breaks down a bit.
Related
Sorry for the lengthy post I'm trying to give as much information as I can and I did my best to format everything to be as easily readable as possible. I've been trying to decompress GIF's in C# and seem to have everything except the LZW decompression down. I am reading in the Gif from a URL. For this example, I will be using this Animated GIF. Which I know has 35 Frames but I only want to look at the first one.
HEADER: 474946383961
GIF Version: 89a
LOGICAL DESCRIPTOR: 41003D00F60000
Width : 65
Height: 61
Sorted Color Table: False
Global Color Table Size: 128
Background Color Index: 0
Pixel Bits: 0
Below is the Global Color Table, something I am slightly confused about because it is filled 123/128 colors and the rest are 000000s, do I discredit this while filling the code table?
Sorry about the format here, only showing it for the question regarding the 000000s
Global Color Table:
141414 181818 1C1C1C 242424 262626 282828 2A2A2A 2C2C28 302C2C 30302C 3430303 434303
434344 030185 030284 03C346 038306 438306 43C305 044245 048245 448285 C50285C 502C5C
542C5C 543054 503860 542C68 50286C 50286C 542870 542870 542C70 582874 582870 582C745
82C745 C2C785 C2C605 830645 830645 C30645 C34685 C307C6 02C6C6 0346C6 438746 434786
030786 838786 C3C006 464806 02C806 42C806 430846 C34886 C348C7 034847 43C887 0388C7
43C887 83C8C7 83C907 034947 034947 434987 434947 438987 4389C7 8389C7 C38A07 838A07
C388C7 C40A46 050A48 03C948 048A08 848A08 C48A89 04CA89 44CAC9 44CAC9 850B09 C50B49
C50B49 C54B4A 054BCA 050B8A 054B8A 454BCA 454BCA 458BCA C5CC0A 454C0A 854C0A 858C4A
858C4A C58C4A C5CC8A C58C8A C5CC4B 058C8B 058C8B 05CC89 C64C8B 060CCB 460D0B 860D0B
864D4B C64D4C 068D8C 068D8C 468DCC 468DCC 86CE8D 070ECD 874F0D C78F4D C78F4D C7CF4E
078F8E 07CF8E 47C000 000000 000000 000000 000000 000000
Graphics Control Extension
21F9040D03007B00 |Graphics Control Extension
Block Size: 4
Has Transparency: True
Delay: 768
Transparency Color Index: 123
Image Descriptor
IMAGE DESCRIPTOR: 2C0000000041003D0000
Left: 0
Top: 0
Width : 65
Height: 61
Local Color Table: False
Interlace: False
Finally Where I am confused the Image Data
LZW minimum code size: 7
IMAGE DATA SUBBLOCK 1 HEXDATA:
80 7B 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 86 06 06 90 94 84 07
95 86 05 0C 00 98 94 05 01 07 05 9D 7B 05 0B 9B A3 8F 07 0C 0C 02 05
93 94 07 08 0A 09 9C A8 8D 05 08 B2 04 02 AF A9 09 0B 0A B5 B6 8B 05
00 C0 AB 01 A2 8E 05 BF C0 C2 C3 8A 07 0A 08 AB 0F 19 CA 8C A5 C0 0B
CF D0 88 C5 0C 09 0C 08 6E 29 CB 0C 0B A6 DD DE 87 9A E9 4C 67 2A D8
89 06 0C 0A E9 08 EB EC 85 06 00 BF 58 63 C6 C8 5B 64 40 4B BA 05 B4
F6 11 03 F0 20 60 18 37 03 E9 85 41 90 4E 43 05 85 C4 AA 9C 39 43 E6
8C 0C 15 8A 0A 98 E9 58 A6 0A 05 8C 21 29 90 21 33 86 0C 98 88 99 C0
8C D9 38 E6 22 CA 90 13 58 86 21 23 05 45 81 9F 40 81 5A 09 C8 F2 E4
CD 94 1D 37 5C D0 93 A7 A9 D3 A6 2A 7C 8C 34 63 F2 28 B1 09 14 EE D8
A9 B3 B5 8E 57 AE 76 B8 AC 68 49 66 82 D5 6C 75 E2 A8 55 0B 67 6D 1C
For All intensive purposes We should need to look at the first few binary bits
IMAGE BLOCK BINARY:
10000000 clearcode, 01111011, 10000010, 10000011, 10000100,
10000101, 10000110, 10000111, 10001000, 10001001, 10001010,
10001011, 10001100, 10001101, 10001110, 10001111,
Codes:
1000000, 0011110, 1110000, 01010000... ect
My main question is how do I use LSB Packing order when reading these codes, secondly how does this make sense for each pixel considering the background is transparent, like how do I get the index of the first non transparent pixel. Finally, at what point do I increase the code size for adding codes to the table to LZW Minimum codes size +1(8). Thank you for any advice.
LSB packing order just means to read the data as little-endian and right shift the data as you "eat" the bits.
Here's an example in C, C# makes accessing memory more painful, but the logic would be the same:
uint32_t ulBits;
unsigned char *pData;
int codelen, code, bitnum;
int mask;
int nextcode;
codelen = 7; // assume 7 bits to start
mask = (1<<(codelen+1)) -1;
clearcode = (mask >> 1) + 1;
nextcode = clearcode + 2;
ulBits = *(uint32_t)pData; // read 32-bits as little endian
bitnum = 0;
#define WORDLEN 32
// To read the variable length codes you would do the following:
while (decoding == true)
{
if ((bitnum + codelen) > WORDLEN) // need to read more data
{
pData += (bitnum >> 3); // adjust source pointer
ulBits = *(uint32_t)pData; // read another 32-bits
bitnum &= 7; // reset bit offset
}
code = (ulBits >> bitnum);
code &= mask;
bitnum += codelen;
// some logic here to increment the nextcode is beyond the scope of this answer
<the rest of your logic here>
}
As you decompress the codes, you add a new item to your dictionary and increment your "next code" value. When this value can't fit in the current code size, you increase it by one bit until you hit 4096 and usually start over with a clear code to reset the dictionary. There is a rarely used option called "differed clear code". In this case the full dictionary stays in use until a clear code is received. There are plenty of sample LZW decoders that you can look at, so it's not necessary to post an entire one here.
I have data stored in a file in HEX format and I know some examples of what the corresponding date should be.
However I am unable to determine how to calculate it.
83 61 94 04/08/2015
83 61 75 16/07/2015
83 61 97 07/08/2015
83 0 135 01/01/1999
83 51 64 08/10/2012
I don't know how the date was encoded originally and have no way of finding out as the data file is old and no longer supported by anyone.
any suggestions as to how to convert the hex to the corresponding date??
2015-08-04 - **94** days = 2015-05-02
2015-07-16 - **75** days = 2015-05-02
2015-08-07 - **97** days = 2015-05-02
So the third byte, in its "hexadecimal form" must have to do with the "number of days" and 2015-05-02 should be encoded as 83 61 00 I guess. However you should provide some more examples of other dates with different years so as to understand the other bytes.
EDIT: You new data can tell the following
83 51 64 --> 2012-10-08 - ** 64 ** days = 2012-08-05 (83 51 00)
83 01 35 --> 1999-01-01 - 83 days = 1998-11-27 (83 01 00)
61 - 51 = 10, and there are 1000 days between 2012-08-05 and 2015-05-02 (83 61 00), that means, the second "byte" also give us "days" but with a x100 multiplier.
Try it on the second case (1998-11-27). There are 6000 thousand days from that date to 2015-05-02 (83 61 00). 61-01 = 60 * 100.
I believe your formula should be something like:
Date in "hex" (AA BB CC)
Date = (AA * 1000 + BB * 100 + CC) days + Date_0
And I let you calculate yourself Date_0 as you can use any of the date examples that you have provided.
Note I am assuming AA is multiplied by 1000 as you have not provided any example where the first byte was changed.
As far as I know, the binary representation of DateTime and TimeSpan structures are 8-byte numbers of ticks (1 millisecond = 10000 ticks according to TimeSpan.TicksPerSecond). And values of Days, Hours, Minutes, etc. properties are obtained by integer division on TicksPerDay, TicksPerHour, TicksPerSecond etc. constants of TimeSpan.
For example if You run this code:
TimeSpan s1 = new TimeSpan(3, 5, 7, 9, 11).AddTicks(13));
long t1 = s1.Ticks;
You can get (if you use Visual Studio) something like that in you Memory windows:
0x061BE4D0 3d 2a c9 67 86 02 00 00
0x061BE4E0 3d 2a c9 67 86 02 00 00
where 0x061BE4D0 and 0x061BE4E0 are addresses of s1 and t1 respectively.
(Actually You should write 's1' and '&t1' instead of just 't1' in Address area of Memory window)
Now if You run another snippet of code:
DateTime d1 = new DateTime(1, 1, 3, 5, 7, 9, 11).AddTicks(13);
long t1 = d1.Ticks;
DateTime d2 = DateTime.Now;
long t2 = d2.Ticks;
You'll see for 'd1', '&t1', 'd2', '&t2' respectively the data like shown:
0x061AE438 3d 6a 5f 3d bd 01 00 00
0x061AE430 3d 6a 5f 3d bd 01 00 00
0x061AE424 bd 71 d5 02 3f 9d d0 88
0x061AE41C bd 71 d5 02 3f 9d d0 08
Why does DateTime.Now set the highest bit (0x 80 00 00 00 00 00 00 00) in its binary representation?
If you look at the source code here (not sure exactly which version this is, but you get the idea):
http://www.dotnetframework.org/default.aspx/DotNET/DotNET/8#0/untmp/whidbey/REDBITS/ndp/clr/src/BCL/System/DateTime#cs/1/DateTime#cs
you can see that high bits are applied depending on whether the time is local or not.
From a quick glance over the code, there's a const member called:
private const UInt64 KindLocal = 0x8000000000000000;
which looks as if it's used in the conversion. I'd suspect this is happening because you're using DateTime.Now, which is a local 'Now'. If you used 'UtcNow' it probably would set a different bit.
private const UInt64 KindUtc = 0x4000000000000000;
However, when you get it as 'ticks', it probably returns the unspecified form, which has no top bit set.
private const UInt64 KindUnspecified = 0x0000000000000000;
Basically, you're getting hung up on the inner workings of the struct. If you really want to understand it, then I'd suggest digging through the code. Otherwise, just use it as per the instructions, and it'll work fine for you!
tl;dr;
What I need to be able to do is reverse engineer serial commands so that I can figure out how either the human readable values or the binary values are being serialized into raw serial commands.
IE:
if
66 = 'A1' or '0110 1'
6e = 'A2' or '0110 2'
e6 = 'B1' or '1110 1'
ee = 'B2' or '1110 2'
then
what is A3 or B3, etc.
Im working on a wrapper for an open source automation project.
There is a way to send raw commands, and in theory string multiple commands together.
I've sniffed a few serial commands, and this is what they look like.
[init] [HouseCode | DeviceCode] [ready] [HouseCode | FunctionCode]
04 66 06 62 // A1 ON
04 6e 06 62 // A2 ON
04 62 06 62 // A3 ON
04 6a 06 62 // A4 ON
04 61 06 62 // A5 ON
04 69 06 62 // A6 ON
04 65 06 62 // A7 ON
04 6d 06 62 // A8 ON
04 67 06 62 // A9 ON
04 6f 06 62 // A10 ON
04 63 06 62 // A11 ON
04 6b 06 62 // A12 ON
04 60 06 62 // A13 ON
04 68 06 62 // A14 ON
04 64 06 62 // A15 ON
04 6c 06 62 // A16 ON
04 e6 06 e2 // B1 ON
04 ee 06 e2 // B2 ON
04 e2 06 e2 // B3 ON
04 ea 06 e2 // B4 ON
....
04 ec 06 e2 // B16 ON
04 66 06 63 // A1 Off
04 e6 06 e3 // B1 Off
04 66 06 61 // All A lights On (using A1 as the starting point)
04 e6 06 e1 // All B lights On (using B1 as the starting point)
04 66 06 66 // All A lights Off (using A1 as the starting point)
04 e6 06 66 // All B lights Off (using A1 as the starting point)
04 66 06 64 2a // A1 Dim 20
04 66 06 64 2c // A1 Dim 21
04 66 06 64 2e // A1 Dim 22
04 66 06 65 2a // A1 Bright 20
04 66 06 65 69 // A1 Bright 50
What I need to be able to do is reverse engineer this so that I can make the serial calls programmatically, or better yet, figure out how either the human readable values or the binary values are being serialized into raw serial commands.
Yes, I could sniff ALL the commands and store each value separately, but I'd like to know how this has been done.
Here's my current observation.
The calls are broken up into two.
04 is initiated and tells the device what to look for
** tells the system which device is being controlled [HouseCode & DeviceCode]
hex 55 is returned to tell you it's ready
06 is initiated and tells the device what to expect
** tells the system the house code and command [HouseCode & FunctionCode]
** is optionally sent and is a value between 0 & 100 to reference a dim level
hex 55 is sent back again to tell you it's ready
The second pair uses the first character as the alphabetic code (HouseCode = A, B, C, etc) and the second character is the address (DeviceCode = 1, 2, 3, etc)
with this information, my personal guess is that...
6 must directly correspond to A
e must directly correspond to B
The forth pair starts with the same HouseCode as the second pair
The forth pair ends with the FunctionCode
1 = all on
2 = on
3 = off
4 = dim
5 = bright
6 = all off
etc..
The fifth pair only shows on a bright/dim command and represents the number between 0 and 100
Lastly, in the docs, each of the commands relate to Binary data, so it's probably not a matter of converting A1 to hex, but rather the binary to hex.
HouseCode DeviceCode Binary Value
A 1 0110
B 2 1110
C 3 0010
D 4 1010
E 5 0001
F 6 1001
G 7 0101
H 8 1101
I 9 0111
J 10 1111
K 11 0011
L 12 1011
M 13 0000
N 14 1000
O 15 0100
P 16 1100
FunctionCode Binary Value
All Units Off 0000
All Lights On 0001
On 0010
Off 0011
Dim 0100
Bright 0101
All Lights Off 0110
Extended Code 0111
Hail Request 1000
Hail Acknowledge 1001
Pre-set Dim (1) 1010
Pre-set Dim (2) 1011
Extended Data Transfer 1100
Status On 1101
Status Off 1110
Status Request 1111
Does anyone know how I might go about achieving this?
Heyu is a fantastic open source application for working with X10 devices. They have published a very comprehensive X10 protocol specification based on X10's original doc.
This should take the guess work out of your work. What is significant is that the housecode and unitcode are static maps and can not be computed. The protocol spec specifies exactly how the bitstream is formed. E.g.
PC Interface Description
0x04,0x66 Address A1
0x6a Checksum ((0x04 + 0x66)&0xff)
0x00 OK for transmission.
0x55 Interface ready.
0x86,0x64 Function: A Dim 16/22*100%
0xea Checksum ((0x86 + 0x64)&0xff)
0x00 OK for transmission.
0x55 Interface ready.
Hey, been working at Project Euler, and this one is giving me some problems
By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.
3
7 4
2 4 6
8 5 9 3
That is, 3 + 7 + 4 + 9 = 23.
Find the maximum total from top to bottom of the triangle below:
...
NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)
here's the algorithm I've used to solve it
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Problem18
{
class Program
{
static void Main(string[] args)
{
string triangle = #"75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23";
string[] rows = triangle.Split('\n');
int currindex = 1;
int total = int.Parse(rows[0]);
Console.WriteLine(rows[0]);
for (int i = 1; i < rows.Length; i++)
{
string[] array1 = rows[i].Split(' ');
if (array1.Length > 1)
{
if (int.Parse(array1[currindex - 1]) > int.Parse(array1[currindex]))
{
Console.WriteLine(array1[currindex - 1]);
total += int.Parse(array1[currindex - 1]);
}
else
{
Console.WriteLine(array1[currindex]);
total += int.Parse(array1[currindex]);
currindex++;
}
}
}
Console.WriteLine("Total: " + total);
Console.ReadKey();
}
}
}
now whenever i run it, it comes up with 1064, only 10 less then the solution -- 1074
i haven't found any problems with the algorithm and I did the problem by hand and also came up with 1064, anyone know if the solution is wrong, i'm interpreting the question wrong, or if there's just a flaw in the algorithm?
Here is a graphical description:
Here's what the bottom up method belisarius describes--using the trivial triangle given in problem 18--looks like, just in case the image in his post is confusing to anyone else.
03
07 04
02 04 06
08 05 09 03
03
07 04
02 04 06
08 05 09 03
^^^^^^
03
07 04
10 04 06
08 05 09 03
^^^^^^
03
07 04
10 13 06
08 05 09 03
^^^^^^
03
07 04
10 13 15
^^^^^^
08 05 09 03
03
20 04
10 13 15
^^^^^^
08 05 09 03
03
20 04
10 13 15
^^^^^^
08 05 09 03
03
20 19
^^^^^^
10 13 15
08 05 09 03
23
^^
20 19
10 13 15
08 05 09 03
Your problem is that your algorithm is a greedy algorithm, always finding local maxima. Unfortunately that causes it to miss higher numbers down below because they are directly below lower numbers. For example, if the triangle were only 3 levels, your algorithm would pick 75 + 95 + 47 = 217, while the correct answer is 75 + 64 + 82 = 221.
The correct algorithm will either try every path and choose the one with the highest total, or compute paths from the bottom up (which allows you to avoid trying every one, thus being much faster). I should add that working from the bottom-up is not only much faster (O(n^2) instead of O(2^n)!), but also much easier to write (I did it in about 3 lines of code).
You've written a greedy algorithm, which I don't think fits the requirements here. Here's a quick example to demonstrate that point:
1
2 1
1 1 100
Using your algorithm you'll reach a sum of 4, although the optimal solution is 102.
It is a good question based on dynamic programming. You need to create a 2d data structure(like vector in c++) then follow the bottom to up approach of dp.
The formula is dp[i][j] += max(dp[i + 1][j], dp[i + 1][j + 1]). Try coding on your own then if you are stuck at some point see my solution.
vector< vector<int> > dp(n); // n is the number of rows
for (int i = 0 ; i < n; i++){
for (int j = 0; j <= i; j++){
cin >> val;
dp[i].push_back(val);
}
}
for (int i = n - 2 ; i >= 0; i--)
{
for (int j = 0; j <= i; j++)
dp[i][j] += max(dp[i + 1][j], dp[i + 1][j + 1]);
}
cout << dp[0][0] << endl;
return 0;
}
input: 3
2
4 5
6 8 9
output: 16
Recursive (not necessarily the best) approach:
static int q18(){
int matrix[][] = // BIG MATRIX;
return getMaxPath(matrix, 0, 0, 0);
}
static int getMaxPath(int matrix[][], int sum, int row, int col){
if(row==matrix.length) return sum;
return Math.max(getMaxPath(matrix, sum+matrix[row][col], row+1, col),
getMaxPath(matrix, sum+matrix[row][col], row+1, col+1));
}