1 00:00:00,000 --> 00:00:02,420 [SQUEAKING] 2 00:00:02,420 --> 00:00:04,356 [RUSTLING] 3 00:00:04,356 --> 00:00:06,776 [CLICKING] 4 00:00:13,560 --> 00:00:15,510 JUSTIN SOLOMON: So today, we're going 5 00:00:15,510 --> 00:00:19,980 to continue in our discussion of dynamic programming. 6 00:00:19,980 --> 00:00:23,070 I actually found this set of problem session problems 7 00:00:23,070 --> 00:00:26,610 to be easier than the previous one. 8 00:00:26,610 --> 00:00:29,190 There's a funny thing, which is we 9 00:00:29,190 --> 00:00:32,820 learned in class about pseudo polynomial time style 10 00:00:32,820 --> 00:00:34,470 dynamic programs. 11 00:00:34,470 --> 00:00:38,220 Somehow, that language is a little bit liberating, 12 00:00:38,220 --> 00:00:40,650 in the sense that you're using parameters that you really 13 00:00:40,650 --> 00:00:44,160 shouldn't, when it comes to the runtime of your algorithm. 14 00:00:44,160 --> 00:00:46,770 Well, I suppose we should, in the sense that it's allowed, 15 00:00:46,770 --> 00:00:49,230 if you call your algorithm pseudo polynomial time. 16 00:00:49,230 --> 00:00:50,950 But it somehow makes it a little easier 17 00:00:50,950 --> 00:00:52,950 to formulate your dynamic programming algorithm, 18 00:00:52,950 --> 00:00:56,220 because all the numbers are staring you right in the face. 19 00:00:56,220 --> 00:00:58,890 You don't have to be so careful about what's fair game 20 00:00:58,890 --> 00:01:02,910 and what's not, when you post your algorithm so long as it's 21 00:01:02,910 --> 00:01:06,460 efficient in the values that you care about. 22 00:01:06,460 --> 00:01:10,130 And so today's problem session has five problems squeezed 23 00:01:10,130 --> 00:01:11,722 instead of the usual four. 24 00:01:11,722 --> 00:01:13,680 We'll see how far we get, seeing that I usually 25 00:01:13,680 --> 00:01:15,157 talk too much anyway. 26 00:01:15,157 --> 00:01:16,740 But I'll try to stay on schedule here, 27 00:01:16,740 --> 00:01:19,710 and we'll see how well we do. 28 00:01:19,710 --> 00:01:22,115 Any questions from our students about dynamic programming 29 00:01:22,115 --> 00:01:23,240 before we get started here? 30 00:01:23,240 --> 00:01:25,170 AUDIENCE: You can cut one, if you want. 31 00:01:25,170 --> 00:01:26,462 JUSTIN SOLOMON: We can cut one? 32 00:01:26,462 --> 00:01:29,220 Oh, I will gladly cut one if I run out of time. 33 00:01:29,220 --> 00:01:30,220 Yeah. 34 00:01:30,220 --> 00:01:33,870 OK, so without further ado, let's 35 00:01:33,870 --> 00:01:39,270 get started with coin-crafting, which is problem 9-1 here. 36 00:01:39,270 --> 00:01:42,510 So I suppose it should be Ceal Naffrey 37 00:01:42,510 --> 00:01:48,640 if I were to work through my splinterism properly here. 38 00:01:48,640 --> 00:01:50,400 In any event, we have a thief who's 39 00:01:50,400 --> 00:01:53,400 in desperate need of money, as with many thieves, or else, 40 00:01:53,400 --> 00:01:56,580 of course, they wouldn't resort to the world of prime. 41 00:01:56,580 --> 00:02:03,090 And Ceal Naffrey here has n identical coins. 42 00:02:08,328 --> 00:02:10,120 I've been very self-conscious about the way 43 00:02:10,120 --> 00:02:12,520 that I write the letter I, ever since Eric pointed it out, 44 00:02:12,520 --> 00:02:13,645 and it's only gotten worse. 45 00:02:13,645 --> 00:02:16,750 Now it's inconsistent and hard to read. 46 00:02:16,750 --> 00:02:21,400 But in any event, so we have n identical coins. 47 00:02:21,400 --> 00:02:24,980 And of course, these coins have very distinctive markings. 48 00:02:24,980 --> 00:02:27,550 And so we can't possibly run away with them 49 00:02:27,550 --> 00:02:30,190 as is, because if you take them to your standard jeweler, 50 00:02:30,190 --> 00:02:32,980 they'll immediately recognize that these markings are 51 00:02:32,980 --> 00:02:33,970 bad and stolen. 52 00:02:33,970 --> 00:02:34,990 And that's not so good. 53 00:02:34,990 --> 00:02:40,690 So instead, we can melt these coins into other objects. 54 00:02:40,690 --> 00:02:46,930 So our sneaky thief here has identified a potential buyer. 55 00:02:46,930 --> 00:02:50,300 And the buyer has a few criteria here. 56 00:02:50,300 --> 00:02:59,002 So we have a buyer, and the buyer has a very strange value 57 00:02:59,002 --> 00:03:00,460 system thing, that apparently, it's 58 00:03:00,460 --> 00:03:04,790 easy to take coins and make them into other things. 59 00:03:04,790 --> 00:03:07,060 But in any event, the buyer, what they care about 60 00:03:07,060 --> 00:03:09,610 is not the fact that the coins are made of gold, 61 00:03:09,610 --> 00:03:13,180 but rather that they like particular objects better 62 00:03:13,180 --> 00:03:16,000 than others made out of said gold. 63 00:03:16,000 --> 00:03:18,880 So in particular, they have a different rate 64 00:03:18,880 --> 00:03:22,690 for each object, a different price they're willing to pay. 65 00:03:22,690 --> 00:03:31,230 And so they have a list of n objects 66 00:03:31,230 --> 00:03:33,360 that they're interested in. 67 00:03:33,360 --> 00:03:40,060 And each one is associated with two things of n objects. 68 00:03:40,060 --> 00:03:42,003 They have a price-- 69 00:03:42,003 --> 00:03:43,920 so the amount that the buyer is willing to pay 70 00:03:43,920 --> 00:03:46,950 for that object, which, again, is not just the weight in gold, 71 00:03:46,950 --> 00:03:48,600 for some reason. 72 00:03:48,600 --> 00:03:53,280 There's a value added tax in this universe. 73 00:03:53,280 --> 00:03:58,594 And it takes a different number of coins to manufacture. 74 00:03:58,594 --> 00:03:59,500 Right? 75 00:03:59,500 --> 00:04:03,990 So maybe I can make a golden chocolate fountain, 76 00:04:03,990 --> 00:04:05,370 and that takes 10 coins. 77 00:04:05,370 --> 00:04:06,620 But I don't want two of those. 78 00:04:06,620 --> 00:04:08,745 So if I make that, then the next thing I have to do 79 00:04:08,745 --> 00:04:12,935 is a figurine of Eric and Jason to put alongside it. 80 00:04:12,935 --> 00:04:14,310 And having more than one of those 81 00:04:14,310 --> 00:04:16,410 would also be creepy and weird. 82 00:04:16,410 --> 00:04:18,959 So I can only make one of each object. 83 00:04:18,959 --> 00:04:22,355 And of course, my goal here is I have n coins. 84 00:04:22,355 --> 00:04:23,730 By the way, the fact that there's 85 00:04:23,730 --> 00:04:28,007 n coins and n objects for the buyer doesn't really matter. 86 00:04:28,007 --> 00:04:29,340 I mean, it will for the runtime. 87 00:04:29,340 --> 00:04:32,070 But you could imagine this being n and m. 88 00:04:32,070 --> 00:04:35,378 So I wouldn't be too hung up on that. 89 00:04:35,378 --> 00:04:37,170 And what you're trying to do is, of course, 90 00:04:37,170 --> 00:04:40,530 maximize your revenue, subject to the constraints 91 00:04:40,530 --> 00:04:44,360 that you have n coins, and you can't make 92 00:04:44,360 --> 00:04:46,190 two objects that are the same. 93 00:04:46,190 --> 00:04:50,020 Hopefully, I've captured the essence of our problem OK. 94 00:04:50,020 --> 00:04:50,930 OK, fabulous. 95 00:04:50,930 --> 00:04:57,440 So as with all of our dynamic programming problems in 6006, 96 00:04:57,440 --> 00:05:00,860 we have a paradigm for how to approach them, 97 00:05:00,860 --> 00:05:04,100 which has a cute acronym, which is SRTBOT 98 00:05:04,100 --> 00:05:07,730 And I think SRTBOT is a totally relevant and straightforward 99 00:05:07,730 --> 00:05:10,370 approach to this problem here. 100 00:05:10,370 --> 00:05:12,740 Yeah, so in particular, let's give ourselves 101 00:05:12,740 --> 00:05:14,730 a bit of notation. 102 00:05:14,730 --> 00:05:17,900 So we're going to number our objects between 1 and n, 103 00:05:17,900 --> 00:05:19,440 just for convenience. 104 00:05:19,440 --> 00:05:27,410 So we'll say that Pi is the price of object i. 105 00:05:30,240 --> 00:05:30,740 OK. 106 00:05:30,740 --> 00:05:36,800 And we'll say that Ki is what the problem calls 107 00:05:36,800 --> 00:05:39,840 the melting number. 108 00:05:39,840 --> 00:05:41,840 In other words, if I want to make object i, 109 00:05:41,840 --> 00:05:43,548 this is the amount of coins that I'd have 110 00:05:43,548 --> 00:05:45,615 to melt to make that object. 111 00:05:45,615 --> 00:05:46,250 OK? 112 00:05:46,250 --> 00:05:49,240 So just a tiny bit of notation. 113 00:05:49,240 --> 00:05:50,710 And in general, so OK, what do we 114 00:05:50,710 --> 00:05:55,720 do when we formulate our dynamic programming problems? 115 00:05:55,720 --> 00:05:58,430 Some problems we could solve that are smaller. 116 00:05:58,430 --> 00:06:01,220 And when we compose them all together, 117 00:06:01,220 --> 00:06:03,500 we get the final solution to our problem. 118 00:06:03,500 --> 00:06:07,330 And this particular problem, involving manufacturing objects 119 00:06:07,330 --> 00:06:10,810 out of coins, I think is a really classic one, when it 120 00:06:10,810 --> 00:06:12,190 comes to dynamic programming. 121 00:06:12,190 --> 00:06:14,500 This is the sort of thing where someday, 122 00:06:14,500 --> 00:06:16,990 when you're trying to pay for your tuition 123 00:06:16,990 --> 00:06:19,053 by doing these hacker contests online, 124 00:06:19,053 --> 00:06:21,220 this is the sort of thing that comes up all the time 125 00:06:21,220 --> 00:06:23,830 in that universe, right? 126 00:06:23,830 --> 00:06:28,865 So in particular, the two variables here, 127 00:06:28,865 --> 00:06:32,150 when I make a new object, is what object did I make? 128 00:06:32,150 --> 00:06:34,890 And how many coins did I spend when I did that? 129 00:06:34,890 --> 00:06:36,710 So those are the two natural parameters 130 00:06:36,710 --> 00:06:39,960 to use, when I solve my dynamic programming problem. 131 00:06:39,960 --> 00:06:40,460 Yeah. 132 00:06:40,460 --> 00:06:42,800 And of course, it's going to be recursive, in the sense 133 00:06:42,800 --> 00:06:47,590 that I can either choose to make object i or not. 134 00:06:47,590 --> 00:06:50,420 And it doesn't matter what order I make my objects in 135 00:06:50,420 --> 00:06:52,430 or similarly, what order I spend my coins in, 136 00:06:52,430 --> 00:06:54,260 which is usually a nice property to have 137 00:06:54,260 --> 00:06:56,630 in a dynamic programming universe. 138 00:06:56,630 --> 00:07:02,780 So in particular-- oh, this thing is my nemesis. 139 00:07:02,780 --> 00:07:05,696 This is front. 140 00:07:05,696 --> 00:07:07,322 I think this class is particularly 141 00:07:07,322 --> 00:07:09,780 tough for short people, because it's moving up and down all 142 00:07:09,780 --> 00:07:10,540 the time. 143 00:07:10,540 --> 00:07:16,950 OK, so given our observation here, if we're doing SRTBOT, 144 00:07:16,950 --> 00:07:19,370 so what's our S again? 145 00:07:19,370 --> 00:07:20,370 Let me ask myself that-- 146 00:07:20,370 --> 00:07:21,090 Sub-problems. 147 00:07:21,090 --> 00:07:23,790 Thank you, Professor Demaine. 148 00:07:23,790 --> 00:07:26,800 Then essentially, what we want to do, 149 00:07:26,800 --> 00:07:29,790 based on what I argued verbally, is maybe 150 00:07:29,790 --> 00:07:31,710 define our variable x i, j the thing 151 00:07:31,710 --> 00:07:44,440 we're going to compute, to be the revenue from using i coins 152 00:07:44,440 --> 00:07:47,310 and objects 1 to j. 153 00:07:52,930 --> 00:07:53,620 OK. 154 00:07:53,620 --> 00:07:56,350 So in other words, I have i coins left in the bank, 155 00:07:56,350 --> 00:07:58,793 and I'm only allowed to use the first j objects. 156 00:07:58,793 --> 00:08:01,210 And we can already see that this is kind of a sensible way 157 00:08:01,210 --> 00:08:03,100 to approach this dynamic programming 158 00:08:03,100 --> 00:08:05,197 problem, in the sense that there's 159 00:08:05,197 --> 00:08:06,280 an obvious recursion here. 160 00:08:06,280 --> 00:08:07,405 I choose to make an object. 161 00:08:07,405 --> 00:08:09,020 I have fewer coins. 162 00:08:09,020 --> 00:08:13,900 And I can sort of imagine there being a topological order, 163 00:08:13,900 --> 00:08:16,720 in the sense that I could first decide about object 1, 164 00:08:16,720 --> 00:08:19,820 and then object 2, and object 3, and so on, or vice versa, 165 00:08:19,820 --> 00:08:23,620 depending on whether you're a prefix or suffix kind of guy-- 166 00:08:23,620 --> 00:08:25,330 which I still get backward. 167 00:08:25,330 --> 00:08:27,900 But the good news is that it doesn't really matter. 168 00:08:27,900 --> 00:08:30,190 What matters is formulating the equation. 169 00:08:30,190 --> 00:08:33,880 OK, any questions about our definition of the thing 170 00:08:33,880 --> 00:08:37,220 that we're going to chase after here? 171 00:08:37,220 --> 00:08:39,789 Fabulous. 172 00:08:39,789 --> 00:08:48,020 Ah-- OK, right. 173 00:08:48,020 --> 00:08:51,440 So let's continue SRTBOT. 174 00:08:51,440 --> 00:08:54,590 So our next piece of our puzzle here 175 00:08:54,590 --> 00:08:57,450 is the R. I believe R stands for recursion. 176 00:08:57,450 --> 00:08:58,970 This is a new acronym for me, too. 177 00:08:58,970 --> 00:09:00,470 Ope, no, Relate. 178 00:09:00,470 --> 00:09:01,860 But it might as well be Recursion 179 00:09:01,860 --> 00:09:04,430 for most of these problems. 180 00:09:04,430 --> 00:09:07,460 Right, so the basic relationship here is that, of course, 181 00:09:07,460 --> 00:09:13,430 I can either use object j, or I can not use object j. 182 00:09:13,430 --> 00:09:17,240 And in both of those cases, If j is the very last guy 183 00:09:17,240 --> 00:09:19,190 that I'm going to consider, that'll 184 00:09:19,190 --> 00:09:21,830 be a totally reasonable recursive rule, right? 185 00:09:21,830 --> 00:09:25,885 So in particular, I have that xi, 186 00:09:25,885 --> 00:09:31,250 j essentially can take one of two values. 187 00:09:31,250 --> 00:09:34,880 That's a parenthesis, in case you're wondering. 188 00:09:34,880 --> 00:09:38,580 And of course, you're trying to maximize your revenue. 189 00:09:38,580 --> 00:09:40,260 So let's do that, OK? 190 00:09:40,260 --> 00:09:49,537 So we have two potential options. 191 00:09:49,537 --> 00:09:50,870 But we have to be a bit careful. 192 00:09:50,870 --> 00:09:53,570 Is there a case where I can't make object j? 193 00:09:56,270 --> 00:09:59,567 Yes, class, there is, which is the case where 194 00:09:59,567 --> 00:10:01,650 I don't have enough coins left in the bank, right? 195 00:10:01,650 --> 00:10:03,770 So I want to make that really expensive fountain, 196 00:10:03,770 --> 00:10:04,850 but I only have one coin. 197 00:10:04,850 --> 00:10:07,100 Then I'm out of luck, yeah? 198 00:10:07,100 --> 00:10:09,310 So let's do these two cases. 199 00:10:09,310 --> 00:10:21,230 So first, if-- oops, I got my cases backward. 200 00:10:21,230 --> 00:10:22,230 That's OK. 201 00:10:22,230 --> 00:10:22,730 Right. 202 00:10:22,730 --> 00:10:26,810 So let's say that I choose not to make object j. 203 00:10:26,810 --> 00:10:28,120 OK, so what does that mean? 204 00:10:28,120 --> 00:10:29,890 So did I spend any coins? 205 00:10:29,890 --> 00:10:30,710 No. 206 00:10:30,710 --> 00:10:33,290 And moreover, what is my maximum profit? 207 00:10:33,290 --> 00:10:35,540 Well, it's going to be the same as the maximum profit, 208 00:10:35,540 --> 00:10:38,210 using objects 1 through j minus 1, 209 00:10:38,210 --> 00:10:39,500 because I didn't use object j. 210 00:10:39,500 --> 00:10:40,000 Yeah? 211 00:10:40,000 --> 00:10:42,200 So in particular, that would be x. 212 00:10:45,450 --> 00:10:47,220 Let's see, I got it backward in my notes, 213 00:10:47,220 --> 00:10:50,350 so we're going to do it live, like that. 214 00:10:50,350 --> 00:10:51,610 OK? 215 00:10:51,610 --> 00:10:55,770 And otherwise, let's say that I did choose to make object j. 216 00:10:55,770 --> 00:10:56,710 Well, what happened? 217 00:10:56,710 --> 00:11:00,160 So I did get some revenue now, right? 218 00:11:00,160 --> 00:11:03,690 Man, what on earth did I write on these notes? 219 00:11:03,690 --> 00:11:07,860 So I get the price of objects j here as my revenue. 220 00:11:07,860 --> 00:11:12,490 But I spent some coins in the process. 221 00:11:12,490 --> 00:11:18,780 So I have i minus K sub i, which is the number of coins. 222 00:11:18,780 --> 00:11:19,280 What's that? 223 00:11:19,280 --> 00:11:20,160 AUDIENCE: K sub j. 224 00:11:20,160 --> 00:11:22,805 JUSTIN SOLOMON: Oh, thank you-- sorry, K sub j. 225 00:11:22,805 --> 00:11:24,930 That's why we should be consistent with our indices 226 00:11:24,930 --> 00:11:28,130 when we write these things down. 227 00:11:28,130 --> 00:11:33,470 So I spent K sub j coins making this thing, object j. 228 00:11:33,470 --> 00:11:36,663 And moreover, I can still choose to make 229 00:11:36,663 --> 00:11:37,830 any of the previous objects. 230 00:11:37,830 --> 00:11:40,580 So it's still just j minus 1. 231 00:11:40,580 --> 00:11:44,290 But I have to be careful, because I can't always do this. 232 00:11:44,290 --> 00:11:48,220 In particular, this had better be a positive number for n, 233 00:11:48,220 --> 00:11:49,910 or at least a non-negative number. 234 00:11:49,910 --> 00:11:52,420 Because if I end up with a negative number of coins, 235 00:11:52,420 --> 00:11:54,910 well, that that's not a physical universe 236 00:11:54,910 --> 00:11:56,900 that I choose to be in. 237 00:11:56,900 --> 00:12:00,550 So in particular, what we need, in some sense, 238 00:12:00,550 --> 00:12:03,190 is i minus k minus j, and k and j 239 00:12:03,190 --> 00:12:05,990 to be greater than or equal to 0. 240 00:12:05,990 --> 00:12:08,975 Or equivalently, i is greater than or equal to K sub j. 241 00:12:08,975 --> 00:12:11,570 I think you guys could all do that one at home. 242 00:12:11,570 --> 00:12:13,310 OK, and this is our recursion. 243 00:12:13,310 --> 00:12:15,518 Hopefully, I've gotten it right, because it disagrees 244 00:12:15,518 --> 00:12:18,590 with the crazy thing I wrote in my notes at 1:00 AM yesterday. 245 00:12:18,590 --> 00:12:20,520 But I think it's pretty straightforward. 246 00:12:20,520 --> 00:12:23,330 Essentially, either I can choose to use the last object, 247 00:12:23,330 --> 00:12:25,160 or I choose not to. 248 00:12:25,160 --> 00:12:27,470 And either one of those, of course, 249 00:12:27,470 --> 00:12:29,930 decrements j, because that's the index 250 00:12:29,930 --> 00:12:31,670 of the object I'm considering. 251 00:12:31,670 --> 00:12:34,975 And I either account for the price, but have to pay in gold, 252 00:12:34,975 --> 00:12:36,350 or I don't account for the price. 253 00:12:36,350 --> 00:12:39,430 So implicitly, there's a 0, and I don't have to pay in gold. 254 00:12:39,430 --> 00:12:41,300 OK, good. 255 00:12:41,300 --> 00:12:43,400 All right, so let's continue with SRTBOT. 256 00:12:43,400 --> 00:12:46,575 We might, later in the session, relax 257 00:12:46,575 --> 00:12:48,200 going through every one of these steps, 258 00:12:48,200 --> 00:12:49,992 because a lot of the arguments are similar. 259 00:12:49,992 --> 00:12:52,490 But for now, we'll do one or two carefully. 260 00:12:52,490 --> 00:12:56,060 So T, I believe, stands for Topological order. 261 00:12:56,060 --> 00:12:57,980 And here, it's staring us in the phase. 262 00:12:57,980 --> 00:13:06,020 Because notice that xi, j only depends 263 00:13:06,020 --> 00:13:11,570 on x question mark, comma, j minus 1. 264 00:13:11,570 --> 00:13:14,450 [LAUGHING] Right? 265 00:13:14,450 --> 00:13:17,510 So of course, on your problem set, 266 00:13:17,510 --> 00:13:19,323 you should write things more carefully. 267 00:13:19,323 --> 00:13:20,990 But the basic point here is that there's 268 00:13:20,990 --> 00:13:23,420 a clear topological order, just by looking 269 00:13:23,420 --> 00:13:24,440 at that second index. 270 00:13:24,440 --> 00:13:27,290 Because if you think of all your x's as variables in a graph, 271 00:13:27,290 --> 00:13:29,640 which we've actually drawn in lecture-- 272 00:13:29,640 --> 00:13:33,930 so maybe these are all the i's and then the j-- 273 00:13:33,930 --> 00:13:37,940 so i goes down, and j goes to the right. 274 00:13:37,940 --> 00:13:39,440 Then essentially, this argument is 275 00:13:39,440 --> 00:13:43,280 saying that all the arrows point left in this graph. 276 00:13:46,395 --> 00:13:48,960 I suppose the way I've drawn my arrows isn't quite accurate. 277 00:13:48,960 --> 00:13:49,990 But it actually doesn't matter. 278 00:13:49,990 --> 00:13:51,573 The only thing that matters is that it 279 00:13:51,573 --> 00:13:53,790 goes from right to left. 280 00:13:53,790 --> 00:13:56,640 But I'm going to erase this, so you don't remember it. 281 00:13:56,640 --> 00:13:58,830 OK. 282 00:13:58,830 --> 00:14:00,553 So in general, just when you want 283 00:14:00,553 --> 00:14:02,220 to make your topological order argument, 284 00:14:02,220 --> 00:14:04,230 I think the totally sensible one is 285 00:14:04,230 --> 00:14:06,180 looking at the indices of recursion 286 00:14:06,180 --> 00:14:09,710 and then just trying to find some number that decreases. 287 00:14:09,710 --> 00:14:12,128 Incidentally, if you take a differential equation course, 288 00:14:12,128 --> 00:14:14,420 that's roughly how you prove that a lot of those things 289 00:14:14,420 --> 00:14:15,930 converge, too. 290 00:14:15,930 --> 00:14:19,136 So there's a generic math check that we use a lot. 291 00:14:19,136 --> 00:14:21,950 What do you call that in ODE where have 292 00:14:21,950 --> 00:14:23,442 some number that decreases? 293 00:14:23,442 --> 00:14:25,400 AUDIENCE: I would call that potential function. 294 00:14:25,400 --> 00:14:26,300 JUSTIN SOLOMON: Potential function-- 295 00:14:26,300 --> 00:14:28,085 that's a perfectly sensible one. 296 00:14:28,085 --> 00:14:29,180 It's not Lipschitz. 297 00:14:29,180 --> 00:14:30,830 It's some other mathematician. 298 00:14:30,830 --> 00:14:34,690 Anyway, OK, so let's continue SRTBOT. 299 00:14:34,690 --> 00:14:38,970 So next we need B, which is our Base case. 300 00:14:38,970 --> 00:14:41,250 So in this case, it's pretty straightforward. 301 00:14:41,250 --> 00:14:45,150 If I don't have any coins, I can't make any money. 302 00:14:45,150 --> 00:14:47,730 I have a t-shirt that says that at home. 303 00:14:47,730 --> 00:14:49,920 And moreover, if I can't sell anything, 304 00:14:49,920 --> 00:14:51,520 I can't make any money. 305 00:14:51,520 --> 00:14:53,460 So those are pretty straightforward cases. 306 00:14:53,460 --> 00:14:59,100 So we have that 0 equals x of 0, comma j. 307 00:14:59,100 --> 00:15:02,820 Remember, the first index is the number of coins you have. 308 00:15:02,820 --> 00:15:05,870 So this is saying, I can't make anything. 309 00:15:05,870 --> 00:15:07,110 I don't have any coins. 310 00:15:07,110 --> 00:15:14,080 And similarly, equals x i, comma 0 for all i, j. 311 00:15:14,080 --> 00:15:18,630 So this is the coins and the objects. 312 00:15:18,630 --> 00:15:20,070 OK. 313 00:15:20,070 --> 00:15:20,850 So let's see. 314 00:15:20,850 --> 00:15:22,800 I keep writing these problem sessions too big 315 00:15:22,800 --> 00:15:24,342 and then spending half of it erasing. 316 00:15:24,342 --> 00:15:26,440 So let's try and fit this on one board here. 317 00:15:26,440 --> 00:15:27,840 So we're going to do SRTBOT. 318 00:15:27,840 --> 00:15:32,040 Then the second-- no, the first O, 319 00:15:32,040 --> 00:15:34,710 because there's no O in SRT-- 320 00:15:34,710 --> 00:15:38,080 is the original problem that you want to solve. 321 00:15:38,080 --> 00:15:43,420 So of course, you start out with n objects and n coins. 322 00:15:43,420 --> 00:15:47,280 So the original problem we want to solve 323 00:15:47,280 --> 00:15:50,070 is equivalent to computing x income n. 324 00:15:50,070 --> 00:15:53,190 And then finally, we've got to do our runtime. 325 00:15:53,190 --> 00:15:57,570 T stands for runtime, or Time, I suppose. 326 00:15:57,570 --> 00:16:00,040 So first of all, how many problems are there? 327 00:16:00,040 --> 00:16:01,980 Well, there's x i, j. 328 00:16:01,980 --> 00:16:05,040 Both I can go from 0 to n. 329 00:16:05,040 --> 00:16:07,380 This is a great way to be off by 1. 330 00:16:07,380 --> 00:16:15,710 So there's n plus 1 squared sub problems. 331 00:16:15,710 --> 00:16:17,720 And how much work does each sub-problem do? 332 00:16:17,720 --> 00:16:19,470 Well, it does boring work. 333 00:16:19,470 --> 00:16:20,660 It's just a formula. 334 00:16:20,660 --> 00:16:21,230 Right? 335 00:16:21,230 --> 00:16:28,080 So there's order 1 work per sub-problem. 336 00:16:28,080 --> 00:16:33,750 So the overall algorithm takes n squared time. 337 00:16:33,750 --> 00:16:37,130 So I promised to do something in our last problem session. 338 00:16:37,130 --> 00:16:38,670 Then I didn't actually do it. 339 00:16:38,670 --> 00:16:42,380 So I did think I would spend just a minute here translating 340 00:16:42,380 --> 00:16:45,722 what this SRTBOT thing would mean in terms of code. 341 00:16:45,722 --> 00:16:47,930 Because I think that it's a little bit implicit here. 342 00:16:47,930 --> 00:16:50,840 In particular, I think this step here, 343 00:16:50,840 --> 00:16:53,203 I mean, you will see that it really clearly 344 00:16:53,203 --> 00:16:54,620 is going to give you an algorithm. 345 00:16:54,620 --> 00:16:58,690 But I think it's kind of easy to, again, just to forget what 346 00:16:58,690 --> 00:16:59,940 your code actually looks like. 347 00:16:59,940 --> 00:17:00,980 And actually, the coding problems 348 00:17:00,980 --> 00:17:03,410 on these problem sessions are almost too interesting 349 00:17:03,410 --> 00:17:05,630 and can obscure it a little bit. 350 00:17:05,630 --> 00:17:07,490 So I thought we'd do a boring problem 351 00:17:07,490 --> 00:17:10,490 and show you that it's really not so hard to do this. 352 00:17:10,490 --> 00:17:13,910 And in fact, we covered two different strategies in class 353 00:17:13,910 --> 00:17:15,920 for how to take SRTBOT and convert it 354 00:17:15,920 --> 00:17:17,000 into a piece of code. 355 00:17:17,000 --> 00:17:21,890 Although, they might have zipped past you in this 2x speed thing 356 00:17:21,890 --> 00:17:24,500 that you can do now. 357 00:17:24,500 --> 00:17:26,250 So here are two options. 358 00:17:26,250 --> 00:17:28,339 One of them is called memoization. 359 00:17:28,339 --> 00:17:30,560 And the other, I don't know, bottom up, I guess, 360 00:17:30,560 --> 00:17:32,132 is a reasonable phrase to describe. 361 00:17:32,132 --> 00:17:33,590 And so I thought we'd do them both, 362 00:17:33,590 --> 00:17:36,440 because they're both easy for this particular problem. 363 00:17:39,440 --> 00:17:41,090 OK. 364 00:17:41,090 --> 00:17:41,660 Right. 365 00:17:41,660 --> 00:17:43,890 So let's do that. 366 00:17:43,890 --> 00:17:47,990 So is this necessary on your homework? 367 00:17:47,990 --> 00:17:49,280 Strictly speaking, no. 368 00:17:49,280 --> 00:17:52,700 If you've gone through SRTBOT, then essentially, everything 369 00:17:52,700 --> 00:17:54,800 that happens after that is boilerplate, 370 00:17:54,800 --> 00:17:58,130 in terms of converting these steps into a piece of code 371 00:17:58,130 --> 00:17:58,850 or an algorithm. 372 00:17:58,850 --> 00:18:00,590 But I do think, just for understanding 373 00:18:00,590 --> 00:18:02,450 why SRTBOT makes sense, it's worth 374 00:18:02,450 --> 00:18:04,350 thinking about for a minute. 375 00:18:04,350 --> 00:18:07,700 So option A here is memoization. 376 00:18:11,410 --> 00:18:13,900 Ironically, I've taught and TA'd algorithms a few times, 377 00:18:13,900 --> 00:18:16,880 and I never actually knew what memoization meant. 378 00:18:16,880 --> 00:18:20,110 So I learned something from Eric's lecture the other day. 379 00:18:20,110 --> 00:18:24,070 Which remember, memoization is the key thing in what, 380 00:18:24,070 --> 00:18:27,190 apparently, is a made-up word, is memo-- 381 00:18:27,190 --> 00:18:30,130 if you're back in the day, and you had a steno pad, 382 00:18:30,130 --> 00:18:31,720 and you were writing down stuff. 383 00:18:31,720 --> 00:18:35,830 Because that's how you solved problems, with your slide rule. 384 00:18:35,830 --> 00:18:40,627 Then essentially, the idea is that, if I compute x i, 385 00:18:40,627 --> 00:18:43,100 j for some i, j pair, I shouldn't compute it again. 386 00:18:43,100 --> 00:18:46,190 I should just write it down on my memo pad. 387 00:18:46,190 --> 00:18:48,020 Stenoization sounds better to me. 388 00:18:48,020 --> 00:18:52,580 But I suppose we'd have to go back to the 1940s and fix it. 389 00:18:52,580 --> 00:18:55,070 OK, so let's actually write down. 390 00:18:55,070 --> 00:18:57,320 I'm going to write down pseudocode, that will probably 391 00:18:57,320 --> 00:19:00,120 look more like Matlab, because I'm that kind of guy. 392 00:19:00,120 --> 00:19:01,790 So let's say that I wanted to make 393 00:19:01,790 --> 00:19:11,490 a function, which, I guess, is revenue of i, j, like that. 394 00:19:11,490 --> 00:19:14,000 Bah. 395 00:19:14,000 --> 00:19:16,632 And this is the thing I wanted to compute. 396 00:19:16,632 --> 00:19:18,965 That's actually going to be a problem, because we're not 397 00:19:18,965 --> 00:19:21,550 going to be able to see. 398 00:19:21,550 --> 00:19:23,350 OK, right. 399 00:19:23,350 --> 00:19:28,510 So in addition to this, I'm going to pass in an array 400 00:19:28,510 --> 00:19:31,855 x, which is going to be like my memo pad. 401 00:19:31,855 --> 00:19:33,730 This is going to be terrible coding practice, 402 00:19:33,730 --> 00:19:36,340 but easy board coding practice. 403 00:19:36,340 --> 00:19:38,650 So if I were in C++, maybe I'm passing by reference, 404 00:19:38,650 --> 00:19:40,560 so that when I edit-- 405 00:19:40,560 --> 00:19:44,320 that's a treble clef, but whatever-- 406 00:19:44,320 --> 00:19:47,310 when I edit x, it actually persists when I recurse. 407 00:19:47,310 --> 00:19:48,760 This is terrible coding practice, 408 00:19:48,760 --> 00:19:50,000 and you shouldn't do it. 409 00:19:50,000 --> 00:19:50,752 OK? 410 00:19:50,752 --> 00:19:52,210 But it's just going to be because I 411 00:19:52,210 --> 00:19:55,480 don't want to write too many lines on the board here. 412 00:19:55,480 --> 00:19:58,000 And maybe we initialize. 413 00:19:58,000 --> 00:20:03,630 We have some helper function to-- 414 00:20:03,630 --> 00:20:06,300 let's see, we want our revenue to be big. 415 00:20:06,300 --> 00:20:08,120 Well, actually no. 416 00:20:08,120 --> 00:20:09,910 We'll just initialize it to not a number, 417 00:20:09,910 --> 00:20:11,910 so that we know that we haven't computed it yet. 418 00:20:11,910 --> 00:20:13,740 How about that? 419 00:20:13,740 --> 00:20:17,807 OK, so what should we do? 420 00:20:17,807 --> 00:20:20,390 Well, if we're going to memoize, the first thing we should do, 421 00:20:20,390 --> 00:20:22,977 any time that I call my revenue function on an i, 422 00:20:22,977 --> 00:20:24,950 j pair is check that I've already computed it. 423 00:20:24,950 --> 00:20:25,940 Yeah? 424 00:20:25,940 --> 00:20:29,668 So in my goofy, bad board-coding style here, what could I do? 425 00:20:29,668 --> 00:20:31,460 I'd say, well, if I've already computed it, 426 00:20:31,460 --> 00:20:33,320 then this thing won't equal NaN anymore 427 00:20:33,320 --> 00:20:34,740 and won't be not a number. 428 00:20:34,740 --> 00:20:42,060 So I can say, OK, if x is not equal to not a number-- 429 00:20:42,060 --> 00:20:45,000 so in other words, it is a number-- 430 00:20:45,000 --> 00:20:45,500 return. 431 00:20:49,210 --> 00:20:52,330 And this, I think that this little line of code here, 432 00:20:52,330 --> 00:20:53,390 it gets a little lost. 433 00:20:53,390 --> 00:20:57,020 But this, we should put sparkles around it. 434 00:20:57,020 --> 00:20:59,590 This is the magic of dynamic programming, 435 00:20:59,590 --> 00:21:03,310 because I just killed recursive calls. 436 00:21:03,310 --> 00:21:07,390 Even if i and j are 17 and 23, if I already computed it, 437 00:21:07,390 --> 00:21:08,290 I'm done, right? 438 00:21:08,290 --> 00:21:10,990 I don't have to call my recursion again. 439 00:21:10,990 --> 00:21:11,950 OK. 440 00:21:11,950 --> 00:21:13,960 And otherwise, what am I going to do? 441 00:21:17,330 --> 00:21:21,008 Well, otherwise, I'll maybe call-- 442 00:21:21,008 --> 00:21:22,300 do I want to write it all down? 443 00:21:22,300 --> 00:21:23,717 I don't want to write it all down. 444 00:21:27,030 --> 00:21:35,000 So otherwise, I'm going to evaluate, R, where 445 00:21:35,000 --> 00:21:36,890 R is this formula over here. 446 00:21:36,890 --> 00:21:43,970 Notice that this will require recursive calls, right? 447 00:21:43,970 --> 00:21:53,131 And I'm going to store it in x i, j and then return x i, j. 448 00:21:57,110 --> 00:21:57,620 OK? 449 00:21:57,620 --> 00:21:59,090 So basically, the only difference 450 00:21:59,090 --> 00:22:01,940 between what we've seen in the first 2/3 of 6006 451 00:22:01,940 --> 00:22:05,930 and now is this beautiful line of code, saying, if I already 452 00:22:05,930 --> 00:22:07,820 computed this thing, return it. 453 00:22:07,820 --> 00:22:11,400 And this is the memoized version of our algorithm. 454 00:22:11,400 --> 00:22:15,380 I think this is the easiest one to maybe think about. 455 00:22:15,380 --> 00:22:16,970 But actually, from a runtime analysis, 456 00:22:16,970 --> 00:22:19,098 it's a little bit annoying. 457 00:22:19,098 --> 00:22:21,140 It's not in the sense that we convinced ourselves 458 00:22:21,140 --> 00:22:22,160 that SRTBOT is OK. 459 00:22:22,160 --> 00:22:24,410 But of course, if you're thinking about your recursion 460 00:22:24,410 --> 00:22:26,990 tree, what's happening is that you're maybe 461 00:22:26,990 --> 00:22:30,140 convincing yourself that this piece can be lopped off 462 00:22:30,140 --> 00:22:31,920 in your function calls. 463 00:22:31,920 --> 00:22:35,850 So you have to do your counting carefully. 464 00:22:35,850 --> 00:22:38,780 There's a different way to implement the same thing. 465 00:22:38,780 --> 00:22:42,198 So this would be option B. This is maybe 466 00:22:42,198 --> 00:22:43,740 more efficient, maybe less efficient, 467 00:22:43,740 --> 00:22:44,823 depending on your problem. 468 00:22:44,823 --> 00:22:47,157 But these are all within constant factors of each other, 469 00:22:47,157 --> 00:22:48,130 for the most part-- 470 00:22:48,130 --> 00:22:49,920 not always, but for the most part. 471 00:22:49,920 --> 00:22:53,400 This would be bottom up. 472 00:22:53,400 --> 00:22:55,650 And this is the idea of, rather than just 473 00:22:55,650 --> 00:22:58,320 taking our recursive algorithm that we already know, 474 00:22:58,320 --> 00:23:01,033 and then just checking a table to say, like, OK, 475 00:23:01,033 --> 00:23:01,950 did I already do this? 476 00:23:01,950 --> 00:23:05,040 And in that case, return it, in the bottom-up version, 477 00:23:05,040 --> 00:23:09,000 I'm going to build up my array x i, j because so there's 478 00:23:09,000 --> 00:23:12,272 no recursion at all. 479 00:23:12,272 --> 00:23:13,480 So what would that look like? 480 00:23:13,480 --> 00:23:16,770 So in the bottom-up case, notice that, in some sense, 481 00:23:16,770 --> 00:23:18,570 memoization is a top-down strategy. 482 00:23:18,570 --> 00:23:20,940 I would call it on n, comma n. 483 00:23:20,940 --> 00:23:22,345 Here, we're going to start from 0 484 00:23:22,345 --> 00:23:23,720 and work our way toward n, right? 485 00:23:23,720 --> 00:23:29,910 So we'll start with x 0, j equals 486 00:23:29,910 --> 00:23:34,590 x i, 0 equals 0 for all i, j. 487 00:23:34,590 --> 00:23:37,710 Obviously, I can do this with a for loop. 488 00:23:37,710 --> 00:23:41,010 And now, well, remember, if we think 489 00:23:41,010 --> 00:23:42,720 about our topological order, x i, 490 00:23:42,720 --> 00:23:45,895 j only depends on previous j's, right? 491 00:23:45,895 --> 00:23:48,270 So it makes sense to have an outer loop, which is over j. 492 00:23:54,600 --> 00:23:58,350 And now, inside of this outer loop, 493 00:23:58,350 --> 00:24:02,460 I can compute anything that I want in that j column of x. 494 00:24:02,460 --> 00:24:05,220 And I'm in good shape, because I'm building it up one column 495 00:24:05,220 --> 00:24:06,400 at a time, right? 496 00:24:06,400 --> 00:24:13,480 So in particular, now we can do our loop over i 497 00:24:13,480 --> 00:24:19,900 and then just have x j and now evaluate our R step 498 00:24:19,900 --> 00:24:22,000 in our SRTBOT paradigm. 499 00:24:22,000 --> 00:24:23,680 And notice that that's perfectly fine. 500 00:24:23,680 --> 00:24:26,425 Because by the time I get to computing x i, 501 00:24:26,425 --> 00:24:29,650 j, I've already filled in x i, j minus 1, 502 00:24:29,650 --> 00:24:32,600 which is all I needed to evaluate that formula. 503 00:24:32,600 --> 00:24:34,740 So what are the advantages and disadvantages here? 504 00:24:34,740 --> 00:24:37,760 So notice that here, our runtime is staring you in the phase. 505 00:24:37,760 --> 00:24:38,260 Right? 506 00:24:38,260 --> 00:24:43,620 We have n squared sub-problems, order 1 work, and you're done. 507 00:24:43,620 --> 00:24:46,820 On the other hand, there's some possibility. 508 00:24:46,820 --> 00:24:49,850 If you were an old-school AI person, 509 00:24:49,850 --> 00:24:55,450 you might be able to do some pruning on your left-hand side 510 00:24:55,450 --> 00:24:56,533 that I can't do over here. 511 00:24:56,533 --> 00:24:57,033 Right? 512 00:24:57,033 --> 00:24:58,480 So here, I'm literally evaluating 513 00:24:58,480 --> 00:25:01,633 every entry of x i, j. 514 00:25:01,633 --> 00:25:03,550 It's not the case for this particular problem, 515 00:25:03,550 --> 00:25:07,913 but maybe x i, j only depends on x i, j minus 5. 516 00:25:07,913 --> 00:25:10,330 This strategy is going to still build up that whole table. 517 00:25:10,330 --> 00:25:12,440 This one, maybe you can skip over some entries. 518 00:25:12,440 --> 00:25:14,090 So in practice, it could help. 519 00:25:14,090 --> 00:25:17,428 On the other hand, here, I've got a bunch of recursive calls 520 00:25:17,428 --> 00:25:18,970 I've put on the stack of my computer, 521 00:25:18,970 --> 00:25:20,532 that here, I don't have. 522 00:25:20,532 --> 00:25:22,990 So I think, actually, because of the overhead of recursion, 523 00:25:22,990 --> 00:25:24,880 typically, the strategy on the right 524 00:25:24,880 --> 00:25:26,980 is preferred; also, for clarity. 525 00:25:26,980 --> 00:25:30,190 But that's a blanket statement that I shouldn't make. 526 00:25:30,190 --> 00:25:34,290 OK, so anyway, I think I've done this problem to death. 527 00:25:34,290 --> 00:25:36,378 Are there any questions here? 528 00:25:36,378 --> 00:25:38,920 I just thought I'd fill in for something I promised last time 529 00:25:38,920 --> 00:25:41,080 and didn't actually do. 530 00:25:41,080 --> 00:25:43,090 OK, fabulous. 531 00:25:43,090 --> 00:25:47,710 So we'll go on to problem 9-2. 532 00:25:47,710 --> 00:25:49,540 So this is continuing from last time 533 00:25:49,540 --> 00:25:52,660 in the saga of Tim the Beaver here. 534 00:25:52,660 --> 00:25:55,300 So I forget what Tim the Beaver was doing in our last problem 535 00:25:55,300 --> 00:25:55,800 session. 536 00:25:55,800 --> 00:26:01,060 But today, Tim the Beaver is going to the career fair. 537 00:26:01,060 --> 00:26:04,390 And as we all know, the only real purpose 538 00:26:04,390 --> 00:26:09,420 of going to a career fair is to pick up free stuff. 539 00:26:12,000 --> 00:26:12,630 We joke. 540 00:26:12,630 --> 00:26:14,160 Actually, you guys should all go to the career fair. 541 00:26:14,160 --> 00:26:15,990 I got my first job out of college 542 00:26:15,990 --> 00:26:19,470 by going to a career fair and haranguing 543 00:26:19,470 --> 00:26:22,270 somebody that picks our booth, until they let me in. 544 00:26:22,270 --> 00:26:27,330 But in any event, so Tim the Beaver 545 00:26:27,330 --> 00:26:28,890 is not interested in getting a job, 546 00:26:28,890 --> 00:26:32,220 but rather just wants swag, just wants free stuff out 547 00:26:32,220 --> 00:26:34,040 of booths at the career fair. 548 00:26:34,040 --> 00:26:35,430 OK? 549 00:26:35,430 --> 00:26:39,700 So in this particular problem, there's n booths-- 550 00:26:39,700 --> 00:26:40,890 is it booths? 551 00:26:40,890 --> 00:26:43,470 It's certainly not boots. 552 00:26:43,470 --> 00:26:44,340 I don't know. 553 00:26:44,340 --> 00:26:47,640 There are n booths, each of which has a swag. 554 00:26:47,640 --> 00:26:52,350 And in particular, each swag has a value 555 00:26:52,350 --> 00:26:54,660 associated to it, which is Ci, which 556 00:26:54,660 --> 00:27:00,780 is the coolness of object i. 557 00:27:00,780 --> 00:27:03,420 It additionally has Wi. 558 00:27:03,420 --> 00:27:07,930 This is the weight of object i. 559 00:27:07,930 --> 00:27:12,690 And just to make this problem verbally difficult 560 00:27:12,690 --> 00:27:16,860 to communicate, there's a W-A-I-T associated with each 561 00:27:16,860 --> 00:27:21,930 object, which is the time it takes to wait in line and pick 562 00:27:21,930 --> 00:27:22,910 up object i. 563 00:27:22,910 --> 00:27:23,410 OK? 564 00:27:23,410 --> 00:27:26,460 And Tim the Beaver, if there's some ridiculously cool object 565 00:27:26,460 --> 00:27:29,970 with a little wait time, he might just keep getting in line 566 00:27:29,970 --> 00:27:31,760 and getting more of that object. 567 00:27:31,760 --> 00:27:37,360 So unlike Ceal Naffrey on our first problem, 568 00:27:37,360 --> 00:27:39,970 Tim the Beaver is perfectly happy to have more than one 569 00:27:39,970 --> 00:27:41,150 of the same thing. 570 00:27:41,150 --> 00:27:41,650 OK. 571 00:27:45,080 --> 00:27:47,660 In addition to this, just to make 572 00:27:47,660 --> 00:27:49,910 this problem, in my opinion, slightly more 573 00:27:49,910 --> 00:27:53,780 annoying and point-losing, Tim the Beaver 574 00:27:53,780 --> 00:27:57,108 also takes one minute to get in line at any booth. 575 00:27:57,108 --> 00:27:59,150 So we're just going to have to remember that when 576 00:27:59,150 --> 00:28:01,610 we account for our time ti. 577 00:28:01,610 --> 00:28:03,620 OK. 578 00:28:03,620 --> 00:28:08,250 So let's continue adding some more constants to our problem. 579 00:28:08,250 --> 00:28:11,750 So each booth has an object which has coolness, Ci, 580 00:28:11,750 --> 00:28:14,690 weight Wi, time ti. 581 00:28:14,690 --> 00:28:17,000 Tim is carrying a bag. 582 00:28:17,000 --> 00:28:25,340 The bag can hold a particular weight. b. 583 00:28:25,340 --> 00:28:32,120 So this is the max weight that Tim can hold in his bag 584 00:28:32,120 --> 00:28:34,490 at any given time. 585 00:28:34,490 --> 00:28:38,870 And finally, Tim is a greedy beaver, 586 00:28:38,870 --> 00:28:44,140 but he also can go home, or go back to his dam, 587 00:28:44,140 --> 00:28:48,450 I suppose, and empty his bag. 588 00:28:48,450 --> 00:28:48,950 Right? 589 00:28:48,950 --> 00:29:00,760 And so h is the amount of time to go home and back 590 00:29:00,760 --> 00:29:03,790 and empty his bag, in the meantime. 591 00:29:03,790 --> 00:29:06,280 And again, just to be annoying, don't 592 00:29:06,280 --> 00:29:09,027 forget he incurs plus 1 to get in the next line. 593 00:29:09,027 --> 00:29:11,110 This is what made my answer wrong, and I'm bitter. 594 00:29:11,110 --> 00:29:12,910 So I'm going to keep complaining about it. 595 00:29:12,910 --> 00:29:14,410 OK. 596 00:29:14,410 --> 00:29:17,240 So of course, what he wants is the max. 597 00:29:20,110 --> 00:29:22,070 What would economists call this? 598 00:29:22,070 --> 00:29:22,900 I don't know. 599 00:29:22,900 --> 00:29:29,955 But for Tim the Beaver, he wants the max total coolness, or MTC, 600 00:29:29,955 --> 00:29:32,080 which is, of course, a number that we're all trying 601 00:29:32,080 --> 00:29:37,600 to optimize, in k minutes. 602 00:29:37,600 --> 00:29:39,880 You might remember those old TV shows, 603 00:29:39,880 --> 00:29:42,070 where you get one minute in a grocery store 604 00:29:42,070 --> 00:29:46,340 to empty the shells into your cart kind of thing. 605 00:29:46,340 --> 00:29:51,340 So he wants to do this, and the computation time 606 00:29:51,340 --> 00:29:54,930 that he's reserved for this is an order nbk. 607 00:29:54,930 --> 00:29:56,330 And I know it's a big setup. 608 00:29:56,330 --> 00:29:59,060 I tried to document all the different constants that 609 00:29:59,060 --> 00:30:00,410 are in this problem. 610 00:30:00,410 --> 00:30:02,210 I don't think I missed any here. 611 00:30:02,210 --> 00:30:03,980 OK, fabulous. 612 00:30:03,980 --> 00:30:06,500 So incidentally, continuing on-- 613 00:30:06,500 --> 00:30:07,490 AUDIENCE: What's k? 614 00:30:07,490 --> 00:30:10,670 JUSTIN SOLOMON: k-- k is the total amount of time 615 00:30:10,670 --> 00:30:18,490 that Tim the Beaver has allotted to do his job fair scavenging. 616 00:30:18,490 --> 00:30:20,682 Fabulous. 617 00:30:20,682 --> 00:30:22,830 Any other? 618 00:30:22,830 --> 00:30:24,180 Cool. 619 00:30:24,180 --> 00:30:26,340 OK. 620 00:30:26,340 --> 00:30:29,190 Notice that this is going to be an example of a problem that 621 00:30:29,190 --> 00:30:31,380 was not kosher in last week's problem session, 622 00:30:31,380 --> 00:30:34,390 in the sense that k is included in our runtime. 623 00:30:34,390 --> 00:30:34,890 Right? 624 00:30:34,890 --> 00:30:35,850 But what is k? 625 00:30:35,850 --> 00:30:37,660 It's just a number. 626 00:30:37,660 --> 00:30:41,950 k doesn't scale in the size of your problem in a linear way. 627 00:30:41,950 --> 00:30:44,550 So it's not going to matter for how we solve our problem 628 00:30:44,550 --> 00:30:48,090 But it is just a feature that's worth pointing out. 629 00:30:48,090 --> 00:30:48,720 OK. 630 00:30:48,720 --> 00:30:51,600 So how do we solve dynamic programming problems? 631 00:30:51,600 --> 00:30:58,110 We use SRTBOT, or a SeƱor BST, if you are watching previous 632 00:30:58,110 --> 00:30:59,880 iterations of this course. 633 00:30:59,880 --> 00:31:04,650 OK, so right, so let's do that. 634 00:31:04,650 --> 00:31:06,520 See, I'm trying to conserve space. 635 00:31:06,520 --> 00:31:09,610 This is not going to end up succeeding. 636 00:31:09,610 --> 00:31:13,230 So again, what are the different sub-problems here? 637 00:31:13,230 --> 00:31:15,930 Well, what are the different things that 638 00:31:15,930 --> 00:31:18,550 are limiting Tim the Beaver? 639 00:31:18,550 --> 00:31:20,280 What are his constraints? 640 00:31:20,280 --> 00:31:22,870 Well, he only has so much time. 641 00:31:22,870 --> 00:31:27,180 And this is going to sound more philosophical in intent, 642 00:31:27,180 --> 00:31:29,840 but time always moves forward for Tim the Beaver. 643 00:31:29,840 --> 00:31:32,580 So this is a pretty good candidate 644 00:31:32,580 --> 00:31:34,435 in terms of dynamic programming. 645 00:31:34,435 --> 00:31:36,810 Because there's not going to be some cyclical dependency. 646 00:31:36,810 --> 00:31:38,460 Remember that in dynamic programming, 647 00:31:38,460 --> 00:31:41,160 we're all about trying to identify topological orderings 648 00:31:41,160 --> 00:31:42,580 in our sub-problems. 649 00:31:42,580 --> 00:31:44,700 And when you see something like time, 650 00:31:44,700 --> 00:31:48,690 not only does it also begin with t, but it's useful in the sense 651 00:31:48,690 --> 00:31:50,460 that time moves forward. 652 00:31:50,460 --> 00:31:53,640 There's never a case where Tim the Beaver 653 00:31:53,640 --> 00:31:56,280 purchases a weird Warp Speed airplane 654 00:31:56,280 --> 00:31:58,638 and somehow goes back in time. 655 00:31:58,638 --> 00:32:00,930 That doesn't happen in this particular homework problem 656 00:32:00,930 --> 00:32:02,470 and for Tim the Beaver's for sake, 657 00:32:02,470 --> 00:32:04,040 I hope in no homework problems. 658 00:32:07,057 --> 00:32:08,640 So this is a long-winded way of saying 659 00:32:08,640 --> 00:32:11,190 that time is a pretty reasonable constraint 660 00:32:11,190 --> 00:32:14,280 to put in our problem, not a constraint as much as an index, 661 00:32:14,280 --> 00:32:15,840 I guess. 662 00:32:15,840 --> 00:32:18,210 Moreover, there's another thing which 663 00:32:18,210 --> 00:32:21,000 is limiting Tim the Beaver, which 664 00:32:21,000 --> 00:32:22,660 is the capacity of his bag. 665 00:32:22,660 --> 00:32:25,650 Remember, he can only hold weight b. 666 00:32:25,650 --> 00:32:28,830 But this one should give you the heebie-jeebies a little bit. 667 00:32:28,830 --> 00:32:31,920 Because this problem, as a twist, 668 00:32:31,920 --> 00:32:35,730 has allowed the bag to empty itself out. 669 00:32:35,730 --> 00:32:37,530 So it's not true that somehow, you 670 00:32:37,530 --> 00:32:42,690 can come up with sub-problems where Tim the Beaver is just 671 00:32:42,690 --> 00:32:46,250 monotonically decreasing the weight of his bag. 672 00:32:46,250 --> 00:32:50,290 However, if he does choose to decrease the weight of his bag, 673 00:32:50,290 --> 00:32:51,710 he has to spend time doing it. 674 00:32:51,710 --> 00:32:54,680 So time continues to move forward for Tim the Beaver. 675 00:32:54,680 --> 00:32:57,280 And that's what's going to give us our topological order. 676 00:32:57,280 --> 00:32:57,877 Yeah? 677 00:32:57,877 --> 00:32:59,710 This is a little too philosophical, I guess. 678 00:32:59,710 --> 00:33:02,710 But in some sense, this is a long-winded way of saying, 679 00:33:02,710 --> 00:33:07,630 for our SRTBOT paradigm here, a totally reasonable thing to do 680 00:33:07,630 --> 00:33:12,163 would be to have x i, j-- 681 00:33:12,163 --> 00:33:14,890 I don't think, in this class, we do this definition notation. 682 00:33:14,890 --> 00:33:24,790 So just x i, j equals the max coolness 683 00:33:24,790 --> 00:33:32,610 where he has i minutes, and he has j weight-- 684 00:33:35,370 --> 00:33:36,960 let me glance at my answer to see 685 00:33:36,960 --> 00:33:40,350 if it's left in his bag or weight that he's carrying. 686 00:33:40,350 --> 00:33:42,390 Left in his bag-- 687 00:33:42,390 --> 00:33:45,090 either one would make a reasonable problem. 688 00:33:45,090 --> 00:33:47,253 I'm just bad at looking at my notes 689 00:33:47,253 --> 00:33:48,920 and seeing them disagree with the board. 690 00:33:48,920 --> 00:33:51,330 So I'm going to try and stay consistent. 691 00:33:51,330 --> 00:33:56,400 OK, so x i, j is the MTC, but in i minutes with j weight left, 692 00:33:56,400 --> 00:34:00,890 rather than in k minutes with b weight, which is 693 00:34:00,890 --> 00:34:02,660 going to be our base problem. 694 00:34:02,660 --> 00:34:03,440 OK. 695 00:34:03,440 --> 00:34:05,885 Oh no, I did it out of order. 696 00:34:05,885 --> 00:34:06,510 Disregard that. 697 00:34:06,510 --> 00:34:08,100 We'll get to the b in a minute. 698 00:34:08,100 --> 00:34:08,600 OK. 699 00:34:16,909 --> 00:34:21,285 OK, so that's our sub-problems. 700 00:34:24,929 --> 00:34:29,196 So now let's do the R in SRTBOT. 701 00:34:29,196 --> 00:34:31,882 [LAUGHING] I hate this classroom so much. 702 00:34:34,726 --> 00:34:35,900 I'm sorry. 703 00:34:35,900 --> 00:34:40,659 So right, so let's say that Tim the Beaver has i minutes left 704 00:34:40,659 --> 00:34:41,920 on the clock. 705 00:34:41,920 --> 00:34:43,690 And he has j weight in his bag. 706 00:34:43,690 --> 00:34:46,820 He's got a number of actions that he can take. 707 00:34:46,820 --> 00:34:47,538 Yeah? 708 00:34:47,538 --> 00:34:49,580 And let's think about what all those actions are. 709 00:34:49,580 --> 00:34:54,409 By the way, there's one thing that plausibly, Tim the Beaver 710 00:34:54,409 --> 00:34:55,040 could do. 711 00:34:55,040 --> 00:34:58,640 But he doesn't really need to, is do nothing now, but then 712 00:34:58,640 --> 00:35:01,908 in 10 seconds, do something. 713 00:35:01,908 --> 00:35:03,700 You could account for that in this problem, 714 00:35:03,700 --> 00:35:05,380 but there's not a reason, right? 715 00:35:05,380 --> 00:35:07,120 He might as well stack up all his actions 716 00:35:07,120 --> 00:35:11,025 and then leave all of his leftover time at the end. 717 00:35:11,025 --> 00:35:12,900 You convince yourself that that's sort of OK. 718 00:35:12,900 --> 00:35:15,980 Tim prefers a compressed schedule. 719 00:35:15,980 --> 00:35:16,480 Right. 720 00:35:16,480 --> 00:35:18,535 So he's got a lot of energy, this Beaver. 721 00:35:18,535 --> 00:35:19,410 That's what they say. 722 00:35:19,410 --> 00:35:23,520 They're nature's construction workers, something? 723 00:35:23,520 --> 00:35:25,450 OK. 724 00:35:25,450 --> 00:35:28,570 All right, so let's think about all of our options. 725 00:35:28,570 --> 00:35:32,263 So for one, Tim the Beaver could not do a damn thing. 726 00:35:32,263 --> 00:35:34,180 He could just sit around for the rest of time, 727 00:35:34,180 --> 00:35:36,220 and that would be perfectly fine. 728 00:35:36,220 --> 00:35:39,690 So a different way of putting that is that he could give up. 729 00:35:39,690 --> 00:35:43,950 How much coolness would Tim get from giving up? 730 00:35:43,950 --> 00:35:44,610 0. 731 00:35:44,610 --> 00:35:45,930 That's right, kids. 732 00:35:45,930 --> 00:35:49,230 Giving up makes you zero cool. 733 00:35:49,230 --> 00:35:53,760 So OK, so Tim the Beaver is trying to maximize. 734 00:35:53,760 --> 00:35:55,330 He has a lot of different options. 735 00:35:55,330 --> 00:36:02,850 One of them is 0, meaning he gave up. 736 00:36:02,850 --> 00:36:03,350 Right? 737 00:36:03,350 --> 00:36:04,600 Notice he could recurse. 738 00:36:04,600 --> 00:36:06,880 Like, x-- I guess what would be-- 739 00:36:06,880 --> 00:36:11,140 he could give up for one minute, and have that be x i minus 1j, 740 00:36:11,140 --> 00:36:12,760 or something. 741 00:36:12,760 --> 00:36:14,880 I forget if I'm going to do i plus 1 or i 742 00:36:14,880 --> 00:36:17,553 minus 1. i minus 1j. 743 00:36:17,553 --> 00:36:18,470 But there's no reason. 744 00:36:18,470 --> 00:36:20,175 He can just give up and stop. 745 00:36:20,175 --> 00:36:21,800 That would just be extra recursive cost 746 00:36:21,800 --> 00:36:23,820 for no good reason. 747 00:36:23,820 --> 00:36:24,320 OK. 748 00:36:24,320 --> 00:36:25,940 The next thing that he could do is 749 00:36:25,940 --> 00:36:28,160 he could get in line for a booth. 750 00:36:28,160 --> 00:36:29,480 Right? 751 00:36:29,480 --> 00:36:32,030 So first, let's work out what happens then. 752 00:36:32,030 --> 00:36:35,150 So for one, he gets coolness. 753 00:36:35,150 --> 00:36:37,160 Let's say that he gets into booth k. 754 00:36:37,160 --> 00:36:40,790 So he gets coolness Ck when he does that. 755 00:36:40,790 --> 00:36:42,848 And now he can recurse. 756 00:36:42,848 --> 00:36:44,640 So first, you have to account for the time. 757 00:36:44,640 --> 00:36:48,380 So it takes tk-- 758 00:36:48,380 --> 00:36:51,820 that's a t-- time. 759 00:36:51,820 --> 00:36:52,540 Or does it? 760 00:36:52,540 --> 00:36:53,050 No. 761 00:36:53,050 --> 00:36:54,717 Because it takes an extra minute for him 762 00:36:54,717 --> 00:36:56,950 to get in the next line, or to get in this line. 763 00:36:56,950 --> 00:37:00,100 I guess this is better. 764 00:37:00,100 --> 00:37:07,180 And moreover, he needs to account for j minus Wk, 765 00:37:07,180 --> 00:37:08,140 like that. 766 00:37:08,140 --> 00:37:09,250 Can he always do this? 767 00:37:09,250 --> 00:37:12,280 No, he needs to have this much time remaining, 768 00:37:12,280 --> 00:37:15,220 and he needs this much time in his bag-- 769 00:37:15,220 --> 00:37:20,218 or this much weight remaining in his bag. 770 00:37:20,218 --> 00:37:21,760 You guys can work out the inequality. 771 00:37:21,760 --> 00:37:23,177 But since I only have a foot here, 772 00:37:23,177 --> 00:37:25,060 I'll just say, if applicable. 773 00:37:27,590 --> 00:37:29,770 This is a great way to lose points on your homework. 774 00:37:29,770 --> 00:37:31,570 But for board-writing, it's OK. 775 00:37:31,570 --> 00:37:34,330 So when I say applicable, I mean these two numbers had better 776 00:37:34,330 --> 00:37:36,510 be greater than or equal to 0. 777 00:37:36,510 --> 00:37:37,440 OK? 778 00:37:37,440 --> 00:37:39,730 And you can do this for all k, right? 779 00:37:39,730 --> 00:37:43,150 So in other words, he can choose to get into booth k. 780 00:37:43,150 --> 00:37:46,690 And Tim has the third option, which is he can go home. 781 00:37:46,690 --> 00:37:47,260 OK? 782 00:37:47,260 --> 00:37:48,620 So what happens if he goes home? 783 00:37:51,200 --> 00:37:53,530 Does Tim the Beaver get cooler when he goes home? 784 00:37:53,530 --> 00:37:56,830 No, I'm afraid to say. 785 00:38:00,010 --> 00:38:02,110 But he does spend time. 786 00:38:02,110 --> 00:38:05,370 So how much time does he spend? 787 00:38:05,370 --> 00:38:05,870 h-- 788 00:38:08,031 --> 00:38:09,656 AUDIENCE: He should have lost coolness. 789 00:38:09,656 --> 00:38:10,906 JUSTIN SOLOMON: What was that? 790 00:38:10,906 --> 00:38:12,680 AUDIENCE: He should have lost coolness. 791 00:38:12,680 --> 00:38:15,320 JUSTIN SOLOMON: He should have lost coolness by going home. 792 00:38:15,320 --> 00:38:18,710 No, home is cool, guys, especially this semester. 793 00:38:18,710 --> 00:38:19,400 Stay home. 794 00:38:19,400 --> 00:38:21,630 Stay indoors. 795 00:38:21,630 --> 00:38:22,130 Right. 796 00:38:22,130 --> 00:38:26,830 So he loses home time h and 1 to get in the next line. 797 00:38:26,830 --> 00:38:28,310 OK? 798 00:38:28,310 --> 00:38:31,530 But he's got a devil's bargain, of sorts. 799 00:38:31,530 --> 00:38:36,590 He loses time, but he gains bag, bagginess. 800 00:38:36,590 --> 00:38:40,310 Weight is the word that I'm looking for, b, like that. 801 00:38:40,310 --> 00:38:41,720 OK? 802 00:38:41,720 --> 00:38:44,420 Again, in this case, remember that he still 803 00:38:44,420 --> 00:38:47,670 needs, if i is greater than h. 804 00:38:47,670 --> 00:38:50,680 Otherwise, he's in trouble. 805 00:38:50,680 --> 00:38:53,490 By the way, I wrote this in an annoying way. 806 00:38:53,490 --> 00:38:55,870 A different way of saying that is i minus h minus 1 807 00:38:55,870 --> 00:38:57,640 is greater than or equal to 0, which 808 00:38:57,640 --> 00:38:59,807 is really what's applicable in every recursive call. 809 00:38:59,807 --> 00:39:01,930 But this is strict greater than [INAUDIBLE].. 810 00:39:01,930 --> 00:39:03,250 There's another little thing that caught me up, when 811 00:39:03,250 --> 00:39:04,810 I was reading the answer here. 812 00:39:04,810 --> 00:39:07,100 OK, and those are all the options for Tim the Beaver, 813 00:39:07,100 --> 00:39:08,740 yeah? 814 00:39:08,740 --> 00:39:10,840 Notice that every one of our options 815 00:39:10,840 --> 00:39:16,070 either gives up completely or decreases time. 816 00:39:16,070 --> 00:39:19,270 So we have our topological order, 817 00:39:19,270 --> 00:39:21,910 which is, again, the arrow of time 818 00:39:21,910 --> 00:39:23,402 always continues to move forward. 819 00:39:23,402 --> 00:39:25,610 I'm going to prove that rigorously by putting a check 820 00:39:25,610 --> 00:39:28,450 mark next to the letter T. Again, on your homework, 821 00:39:28,450 --> 00:39:30,400 you should write out your answers. 822 00:39:30,400 --> 00:39:33,780 What is our base case for Tim? 823 00:39:33,780 --> 00:39:39,940 Well, how much coolness do you get, if you have no time? 824 00:39:39,940 --> 00:39:40,830 0 coolness. 825 00:39:40,830 --> 00:39:42,610 That's how much. 826 00:39:42,610 --> 00:39:52,550 So we have this expression, x0j equals 0 for all j. 827 00:39:52,550 --> 00:39:54,990 Incidentally, although it's perfectly fine 828 00:39:54,990 --> 00:39:57,840 to have this be your base case, actually, in some sense, 829 00:39:57,840 --> 00:39:59,820 I didn't need it, because Tim the Beaver always 830 00:39:59,820 --> 00:40:01,315 had the option of giving up. 831 00:40:01,315 --> 00:40:02,940 So you could, I guess, in this problem, 832 00:40:02,940 --> 00:40:04,820 have no base case, if you really wanted. 833 00:40:04,820 --> 00:40:08,880 It would be OK, but kind of weird. 834 00:40:08,880 --> 00:40:10,697 OK. 835 00:40:10,697 --> 00:40:12,030 And what's our original problem? 836 00:40:12,030 --> 00:40:16,860 Well, he starts out with time k and weight capacity b 837 00:40:16,860 --> 00:40:17,880 in his bag. 838 00:40:17,880 --> 00:40:20,790 So it's x k, b. 839 00:40:20,790 --> 00:40:25,300 And then finally, we need to do our runtime analysis. 840 00:40:25,300 --> 00:40:26,890 So how many sub-problems are there? 841 00:40:26,890 --> 00:40:29,070 Well, again, a sub-problem is basically 842 00:40:29,070 --> 00:40:32,100 just the number of indexes for most of our dynamic programming 843 00:40:32,100 --> 00:40:33,010 problems. 844 00:40:33,010 --> 00:40:33,510 Right? 845 00:40:33,510 --> 00:40:38,450 So the first index is time. 846 00:40:38,450 --> 00:40:42,440 The second one is bag size. 847 00:40:42,440 --> 00:40:43,790 This is always between 0 and b. 848 00:40:43,790 --> 00:40:45,890 This is always between 0 and k. 849 00:40:45,890 --> 00:40:52,790 So there's order kb sub-problems. 850 00:40:52,790 --> 00:40:55,190 How much time does each sub-problem take? 851 00:40:55,190 --> 00:40:57,470 Well, notice that I have to loop over all 852 00:40:57,470 --> 00:40:59,910 of my different options k here. 853 00:40:59,910 --> 00:41:09,133 So I incur-- oh, I'm noticing k is abused in our answer 854 00:41:09,133 --> 00:41:09,800 to this problem. 855 00:41:09,800 --> 00:41:12,510 We should use k only once. 856 00:41:12,510 --> 00:41:15,518 OK, so here's where I made a mistake. 857 00:41:15,518 --> 00:41:17,310 And I believe it's in the written solution, 858 00:41:17,310 --> 00:41:18,932 but I'm not going to take now. 859 00:41:18,932 --> 00:41:21,570 There's k, which is the total time that Tim the Beaver has, 860 00:41:21,570 --> 00:41:24,210 and there's the k that I use as an index here. 861 00:41:24,210 --> 00:41:25,650 And those are not the same. 862 00:41:25,650 --> 00:41:30,320 I guess I can make this k bar really fast. 863 00:41:30,320 --> 00:41:32,510 There you go, problem solved. 864 00:41:32,510 --> 00:41:34,910 And I just noticed that, because I was doing my runtime. 865 00:41:34,910 --> 00:41:37,200 And it's not order k. 866 00:41:37,200 --> 00:41:40,940 It's the loop over all the k bars. 867 00:41:40,940 --> 00:41:42,390 How many k bars are there? 868 00:41:42,390 --> 00:41:44,098 Well, these are all the different booths, 869 00:41:44,098 --> 00:41:45,560 and those are n of those. 870 00:41:45,560 --> 00:41:51,410 So this is order n time per sub-problem, 871 00:41:51,410 --> 00:41:56,810 which gives me a total runtime of order kbn, which, 872 00:41:56,810 --> 00:41:58,390 I believe-- 873 00:41:58,390 --> 00:42:01,917 oh-oh, our desired runtime was order nbk. 874 00:42:01,917 --> 00:42:04,250 But I think we can convince ourselves that indeed, those 875 00:42:04,250 --> 00:42:05,870 are the same thing. 876 00:42:05,870 --> 00:42:10,320 OK, so my apologies for a slight overloaded character here. 877 00:42:10,320 --> 00:42:13,070 But honestly, it's one of those things, if you read the answer, 878 00:42:13,070 --> 00:42:14,487 you probably wouldn't even notice. 879 00:42:14,487 --> 00:42:16,910 But now that I'm saying it out loud, I am. 880 00:42:16,910 --> 00:42:17,450 OK. 881 00:42:17,450 --> 00:42:20,830 And that solves Tim the Beaver's maximization problem. 882 00:42:20,830 --> 00:42:22,460 He's a very cool Beaver. 883 00:42:22,460 --> 00:42:25,203 Any questions about this one? 884 00:42:25,203 --> 00:42:26,620 Notice that both of these problems 885 00:42:26,620 --> 00:42:28,140 are very similar in nature. 886 00:42:28,140 --> 00:42:29,710 I basically just wrote sub-problems 887 00:42:29,710 --> 00:42:32,680 indexed by every possible thing and then enumerated 888 00:42:32,680 --> 00:42:34,450 every possible solution. 889 00:42:34,450 --> 00:42:36,857 I think this is totally sensible. 890 00:42:36,857 --> 00:42:39,190 Again, I remember I had a math Professor in college that 891 00:42:39,190 --> 00:42:40,440 always would use this phrase-- 892 00:42:40,440 --> 00:42:42,280 it's important not to think here. 893 00:42:42,280 --> 00:42:44,195 And I think this is absolutely true 894 00:42:44,195 --> 00:42:45,820 for these dynamic programming problems, 895 00:42:45,820 --> 00:42:49,390 that somehow they look a lot more complicated than they are. 896 00:42:49,390 --> 00:42:50,570 Fabulous. 897 00:42:50,570 --> 00:42:54,730 So problem 3, protein parsing. 898 00:42:54,730 --> 00:42:59,020 Ah, yeah, so this one also got me tripped up for a minute. 899 00:42:59,020 --> 00:43:01,480 Because the runtime they want is not 900 00:43:01,480 --> 00:43:03,310 the runtime of the obvious solution, 901 00:43:03,310 --> 00:43:07,990 but it kind of, sort of is, after a little bit of fixing. 902 00:43:07,990 --> 00:43:09,280 OK. 903 00:43:09,280 --> 00:43:14,410 So Professor Leric Ander has a laboratory. 904 00:43:14,410 --> 00:43:18,032 And that laboratory processes DNA. 905 00:43:18,032 --> 00:43:20,004 Ta-da. 906 00:43:20,004 --> 00:43:22,270 OK, so let me go to my notes here, 907 00:43:22,270 --> 00:43:25,670 because I think they're easier to read. 908 00:43:25,670 --> 00:43:27,860 So a strand of DNA, as we all know, 909 00:43:27,860 --> 00:43:32,840 because we're MIT students, is equal to basically a strand 910 00:43:32,840 --> 00:43:36,260 of characters that are ACTG. 911 00:43:36,260 --> 00:43:39,680 If you ask me to name what those stood for, 912 00:43:39,680 --> 00:43:42,500 I could make a stab at one or two of them. 913 00:43:42,500 --> 00:43:44,870 But I'm a failure of-- 914 00:43:44,870 --> 00:43:47,430 I did not have the GIR, because I went to Stanford. 915 00:43:47,430 --> 00:43:51,200 And this is why I'm apparently a poorly educated person, 916 00:43:51,200 --> 00:43:54,140 according to a person in a faculty meeting. 917 00:43:54,140 --> 00:43:58,160 But in any event, so we have a strand of DNA. 918 00:43:58,160 --> 00:44:00,350 It's basically a long string of characters 919 00:44:00,350 --> 00:44:01,700 that are one of four options. 920 00:44:01,700 --> 00:44:03,860 I'm told that there's sometimes a fifth and a sixth option, 921 00:44:03,860 --> 00:44:04,670 but not too often. 922 00:44:04,670 --> 00:44:07,580 In this problem, there's not. 923 00:44:07,580 --> 00:44:12,030 And moreover, so a strand can be cut up. 924 00:44:12,030 --> 00:44:13,970 So I have this big, long strand, and I'm 925 00:44:13,970 --> 00:44:16,400 looking for certain markers. 926 00:44:16,400 --> 00:44:23,830 In particular, I have a list P of markers, 927 00:44:23,830 --> 00:44:30,220 which are really a sequence of less than or equal to k 928 00:44:30,220 --> 00:44:31,090 nucleotides. 929 00:44:35,500 --> 00:44:38,750 By the way, this really is something that people do. 930 00:44:38,750 --> 00:44:41,890 String searching really is applicable to processing 931 00:44:41,890 --> 00:44:42,760 these DNA strands. 932 00:44:42,760 --> 00:44:43,570 Obviously, . 933 00:44:43,570 --> 00:44:45,280 I think, in practice, these techniques 934 00:44:45,280 --> 00:44:48,010 have to be a lot more resilient to error. 935 00:44:48,010 --> 00:44:50,350 But really, a lot of these algorithms we're covering 936 00:44:50,350 --> 00:44:52,510 are not all that far off from how 937 00:44:52,510 --> 00:44:56,290 people process these giant data sets, which is pretty cool, 938 00:44:56,290 --> 00:44:57,850 I think. 939 00:44:57,850 --> 00:45:00,660 OK, so what are we going to do? 940 00:45:00,660 --> 00:45:02,273 We have a string. 941 00:45:02,273 --> 00:45:03,940 And then we're going to make a division. 942 00:45:08,170 --> 00:45:10,450 So we'll call our string S and our division 943 00:45:10,450 --> 00:45:16,750 D, which kind of looks like d1 to dm, 944 00:45:16,750 --> 00:45:21,220 which are substrings that concatenate 945 00:45:21,220 --> 00:45:23,642 to make the full guy. 946 00:45:30,250 --> 00:45:35,560 So if S is our input string, then a division D 947 00:45:35,560 --> 00:45:38,230 is just like chopping up S into little substrings, 948 00:45:38,230 --> 00:45:40,690 each of which we can give a name little d here. 949 00:45:40,690 --> 00:45:44,230 So big D is the full division. 950 00:45:44,230 --> 00:45:47,320 Little d is all the little pieces. 951 00:45:47,320 --> 00:45:49,547 There's that old song about going through the big D 952 00:45:49,547 --> 00:45:51,670 in [INAUDIBLE], Dallas. 953 00:45:51,670 --> 00:45:54,220 I think it's for divorce. 954 00:45:54,220 --> 00:46:02,970 Right, OK, so the value of a division 955 00:46:02,970 --> 00:46:05,820 is the number of strands. 956 00:46:08,500 --> 00:46:16,270 So strands are these little d's here, that are in our list P. 957 00:46:16,270 --> 00:46:19,090 OK? 958 00:46:19,090 --> 00:46:22,585 So given S and P, what we want is the max value. 959 00:46:26,700 --> 00:46:29,310 And the runtime that we're budgeted 960 00:46:29,310 --> 00:46:31,020 is kind of a weird runtime. 961 00:46:31,020 --> 00:46:33,540 And this should make us a little suspicious. 962 00:46:33,540 --> 00:46:38,460 So the max value is big O of-- 963 00:46:38,460 --> 00:46:41,210 I think I wrote it slightly differently in the problem, 964 00:46:41,210 --> 00:46:45,590 but whatever-- distributed to k, like that. 965 00:46:45,590 --> 00:46:48,980 So it's k mod P plus k squared. mod S. 966 00:46:48,980 --> 00:46:51,470 So we have two terms here, which somehow smells 967 00:46:51,470 --> 00:46:54,720 funny in dynamic programming. 968 00:46:54,720 --> 00:46:56,860 OK. 969 00:46:56,860 --> 00:46:58,280 So what are we to do? 970 00:46:58,280 --> 00:47:01,840 Well, what I did is I ignored our desired runtime, 971 00:47:01,840 --> 00:47:04,660 came up with a dynamic program, and noticed 972 00:47:04,660 --> 00:47:07,360 that it was a little wrong, and then fixed it. 973 00:47:07,360 --> 00:47:08,775 By wrong, I mean it was correct. 974 00:47:08,775 --> 00:47:10,460 It just wasn't fast enough. 975 00:47:10,460 --> 00:47:12,370 OK, so let's do version 1 here-- 976 00:47:16,710 --> 00:47:23,190 1.0, that makes it more accurate, or more precise. 977 00:47:23,190 --> 00:47:25,480 I always confuse those two. 978 00:47:25,480 --> 00:47:29,078 So here's a thing that is going to be a little bit funny. 979 00:47:29,078 --> 00:47:30,620 Because it's going to look like we're 980 00:47:30,620 --> 00:47:32,960 going to have an easy computational problem. 981 00:47:32,960 --> 00:47:35,520 But then it's going to turn out that it's actually too slow. 982 00:47:35,520 --> 00:47:39,230 So in particular, in our S in SRTBOT, 983 00:47:39,230 --> 00:47:43,940 what we could do is say, xi is going 984 00:47:43,940 --> 00:47:50,430 to be the max value of a suffix. 985 00:47:50,430 --> 00:47:52,430 If you're wondering, I don't know the difference 986 00:47:52,430 --> 00:47:53,540 between prefix and suffix. 987 00:47:53,540 --> 00:47:55,165 But I wrote the word suffix in my notes 988 00:47:55,165 --> 00:47:57,050 and checked it at home. 989 00:47:57,050 --> 00:48:01,342 Si, comma, colon-- see, it's suffix, because it starts at i, 990 00:48:01,342 --> 00:48:02,300 and it goes to the end. 991 00:48:02,300 --> 00:48:03,200 AUDIENCE: [INAUDIBLE] 992 00:48:03,200 --> 00:48:04,033 JUSTIN SOLOMON: Huh? 993 00:48:04,033 --> 00:48:06,280 AUDIENCE: No comma. 994 00:48:06,280 --> 00:48:08,830 JUSTIN SOLOMON: In Matlab, it would be a comma. 995 00:48:08,830 --> 00:48:11,860 And that's a colon, and that's an i. 996 00:48:11,860 --> 00:48:12,400 OK. 997 00:48:12,400 --> 00:48:15,550 [LAUGHING] Thanks. 998 00:48:15,550 --> 00:48:17,800 I'm inventing my own programming language on the board 999 00:48:17,800 --> 00:48:19,540 as we go today. 1000 00:48:19,540 --> 00:48:22,840 All right, so and notice this is a reasonable set 1001 00:48:22,840 --> 00:48:23,890 of sub-problems, right? 1002 00:48:23,890 --> 00:48:29,200 Because obviously, if I lop off some piece of my string, 1003 00:48:29,200 --> 00:48:31,540 then the max value I can get is just 1004 00:48:31,540 --> 00:48:33,580 the value of whatever remains. 1005 00:48:33,580 --> 00:48:35,770 So spiritually, this somehow feels 1006 00:48:35,770 --> 00:48:38,625 like the right dynamic programming. 1007 00:48:38,625 --> 00:48:40,000 And indeed, we'll see that it is. 1008 00:48:40,000 --> 00:48:41,740 But it just requires a little bit 1009 00:48:41,740 --> 00:48:44,290 of a list that could be to run on the right time. 1010 00:48:44,290 --> 00:48:45,280 OK? 1011 00:48:45,280 --> 00:48:48,970 So let's do a recursive call. 1012 00:48:48,970 --> 00:48:53,920 And this is actually straightforward. 1013 00:48:53,920 --> 00:48:57,130 At least, the recursive call that you want to make 1014 00:48:57,130 --> 00:48:57,950 is straightforward. 1015 00:48:57,950 --> 00:49:00,010 And then we'll see that there is an equivalent formula, which 1016 00:49:00,010 --> 00:49:01,843 is the one you'll see in the solution, which 1017 00:49:01,843 --> 00:49:03,160 looks more complicated. 1018 00:49:03,160 --> 00:49:04,340 But is the same thing. 1019 00:49:04,340 --> 00:49:06,550 So I'm going to write it as pseudocode 1020 00:49:06,550 --> 00:49:09,190 for our recursive call, rather than as one giant formula, 1021 00:49:09,190 --> 00:49:10,877 because I think it's easier to follow. 1022 00:49:10,877 --> 00:49:12,460 Not pseudocode-- I know that's frowned 1023 00:49:12,460 --> 00:49:16,390 upon in this class, a description of a set of steps 1024 00:49:16,390 --> 00:49:20,260 for obtaining a recursive call, rather than a formula. 1025 00:49:20,260 --> 00:49:25,390 So in particular, we're going to initialize xi to be 0. 1026 00:49:29,080 --> 00:49:30,770 We want to do a maximization problem. 1027 00:49:30,770 --> 00:49:34,240 So initializing a variable to 0 is a sensible thing to do. 1028 00:49:34,240 --> 00:49:35,990 And remember, what can we do here? 1029 00:49:35,990 --> 00:49:37,480 So we're looking at a suffix. 1030 00:49:37,480 --> 00:49:41,350 I could go down my list P of all the different markers, 1031 00:49:41,350 --> 00:49:43,960 see if any of the matches the first couple of characters 1032 00:49:43,960 --> 00:49:45,130 of my string. 1033 00:49:45,130 --> 00:49:47,110 If it does, I get some value, and then I 1034 00:49:47,110 --> 00:49:48,595 hop onto the next thing. 1035 00:49:48,595 --> 00:49:49,620 Does that make sense? 1036 00:49:55,665 --> 00:49:59,820 Oops, I'm realizing I have a slight mistake here. 1037 00:49:59,820 --> 00:50:04,428 Rather than initializing to 0, [LAUGHING] 1038 00:50:04,428 --> 00:50:05,970 I actually have one additional option 1039 00:50:05,970 --> 00:50:07,110 that I forgot to account for. 1040 00:50:07,110 --> 00:50:08,943 Because I could just not use this character. 1041 00:50:08,943 --> 00:50:11,160 I could put it in its own little snippet 1042 00:50:11,160 --> 00:50:12,970 and get no value from it. 1043 00:50:12,970 --> 00:50:16,080 So maybe initially, I make a recursive call like that. 1044 00:50:16,080 --> 00:50:18,150 It would be OK to initialize it to 0 1045 00:50:18,150 --> 00:50:20,490 and then do this-- but whatever. 1046 00:50:20,490 --> 00:50:22,790 Notice we're already seeing the t in our SRTBOT 1047 00:50:22,790 --> 00:50:24,300 start to stick out at us. 1048 00:50:24,300 --> 00:50:27,270 We're going to only depend on bigger indices i. 1049 00:50:27,270 --> 00:50:28,380 OK. 1050 00:50:28,380 --> 00:50:30,660 But in addition to this, this isn't enough, right? 1051 00:50:30,660 --> 00:50:33,090 This would obviously just recurse the end of our list 1052 00:50:33,090 --> 00:50:34,560 and do nothing. 1053 00:50:34,560 --> 00:50:38,860 We get value if we can find a substring that's in our list. 1054 00:50:38,860 --> 00:50:48,540 So what we could do is, for each marker in P-- 1055 00:50:48,540 --> 00:50:50,960 remember P is the list of things that we're looking for-- 1056 00:50:54,350 --> 00:50:57,800 OK, what could I do? 1057 00:50:57,800 --> 00:51:08,960 If the marker matches S starting at i-- 1058 00:51:08,960 --> 00:51:11,690 I'm going to just not even attempt to do Python-- 1059 00:51:11,690 --> 00:51:17,560 starting at i and ending at the length of the marker, well, 1060 00:51:17,560 --> 00:51:18,280 what could I do? 1061 00:51:18,280 --> 00:51:25,170 I could get $1 by matching that object. 1062 00:51:25,170 --> 00:51:27,843 And then I have to hop forward the length of the string 1063 00:51:27,843 --> 00:51:29,010 in my recursive call, right? 1064 00:51:29,010 --> 00:51:35,880 So well, I could do that, or I could not do that. 1065 00:51:35,880 --> 00:51:37,290 And I want to maximize, right? 1066 00:51:37,290 --> 00:51:45,440 So I can keep my old value, or I could get one point 1067 00:51:45,440 --> 00:51:49,310 by using this as my match, plus xi 1068 00:51:49,310 --> 00:51:53,580 plus the length of the marker. 1069 00:51:53,580 --> 00:51:54,890 OK? 1070 00:51:54,890 --> 00:51:57,020 This is actually, in my mind, the simplest 1071 00:51:57,020 --> 00:51:59,280 possible dynamic program you could come up with. 1072 00:51:59,280 --> 00:52:01,760 This is actually a totally fine dynamic program. 1073 00:52:01,760 --> 00:52:03,843 We'll just see that the runtime isn't good enough. 1074 00:52:06,660 --> 00:52:08,988 OK. 1075 00:52:08,988 --> 00:52:10,530 So does everybody agree this is a way 1076 00:52:10,530 --> 00:52:12,060 I could solve this problem, and it 1077 00:52:12,060 --> 00:52:15,810 would give me a correct answer? 1078 00:52:15,810 --> 00:52:17,970 I'll do the TBOT. 1079 00:52:17,970 --> 00:52:18,845 AUDIENCE: [INAUDIBLE] 1080 00:52:18,845 --> 00:52:21,012 JUSTIN SOLOMON: Yeah, that's what we're going to do. 1081 00:52:21,012 --> 00:52:23,150 But we're going to maybe skip some parts of SRTBOT. 1082 00:52:23,150 --> 00:52:26,760 So in particular, what's the topological order? 1083 00:52:26,760 --> 00:52:29,600 Notice that I always look to the right, when I make a recursive 1084 00:52:29,600 --> 00:52:31,430 call. 1085 00:52:31,430 --> 00:52:33,030 What's my base case? 1086 00:52:33,030 --> 00:52:37,040 Well, in this case, it's just a x of 0, I guess, 1087 00:52:37,040 --> 00:52:38,540 because I'm looking forward. 1088 00:52:38,540 --> 00:52:39,200 Oh, I'm sorry. 1089 00:52:39,200 --> 00:52:42,050 My base case is x of the whole length of the string, which 1090 00:52:42,050 --> 00:52:43,670 is going to return 0, right? 1091 00:52:43,670 --> 00:52:47,090 Because if I have no string, I can't get any value out of it. 1092 00:52:47,090 --> 00:52:51,240 The original is x of 0, meaning that I want the whole string. 1093 00:52:51,240 --> 00:52:53,460 And let's actually do the runtime analysis, 1094 00:52:53,460 --> 00:52:56,090 as Jason suggests, because that's, of course, 1095 00:52:56,090 --> 00:52:59,920 the relevant computation here. 1096 00:52:59,920 --> 00:53:05,730 So this is T2, because it's the second T in SRTBOT. 1097 00:53:05,730 --> 00:53:10,580 OK, so how many sub-problems are there? 1098 00:53:10,580 --> 00:53:13,082 Well, I mean, it almost looks like we 1099 00:53:13,082 --> 00:53:14,290 should have a fast algorithm. 1100 00:53:14,290 --> 00:53:18,100 Because our sub-problems are only indexed by i, right? 1101 00:53:18,100 --> 00:53:22,000 So there's one sub-problem for basically each character 1102 00:53:22,000 --> 00:53:23,020 in the string. 1103 00:53:23,020 --> 00:53:26,260 So there's mod S sub-problems total. 1104 00:53:28,880 --> 00:53:32,600 But how much time does it take for each sub-problem? , 1105 00:53:32,600 --> 00:53:35,000 Well let's be careful. 1106 00:53:35,000 --> 00:53:39,850 So there's a for loop over all the markers in P. 1107 00:53:39,850 --> 00:53:47,620 So I know that I incur at least mod P work in my sub-problem. 1108 00:53:47,620 --> 00:53:50,287 Is that all the work that I incur? 1109 00:53:50,287 --> 00:53:52,370 It kind of looks like it, because there's only one 1110 00:53:52,370 --> 00:53:53,537 for loop, and there's an if. 1111 00:53:53,537 --> 00:53:55,260 But how do I check if strings are equal? 1112 00:53:55,260 --> 00:53:58,200 Well, I have to iterate over the length of the string. 1113 00:53:58,200 --> 00:54:01,160 So I incur a second cost, which is checking 1114 00:54:01,160 --> 00:54:02,550 if two strings are equal. 1115 00:54:02,550 --> 00:54:04,587 We know that our strings are at most-- 1116 00:54:04,587 --> 00:54:06,170 well, I didn't actually write it down. 1117 00:54:06,170 --> 00:54:08,000 But the problem tells us that our strings 1118 00:54:08,000 --> 00:54:11,090 are at most length k. 1119 00:54:11,090 --> 00:54:14,900 So I incur another factor of k in every one 1120 00:54:14,900 --> 00:54:16,130 of my sub-problems. 1121 00:54:16,130 --> 00:54:18,710 And that implies that our whole algorithm, 1122 00:54:18,710 --> 00:54:25,150 that I've outlined for you all above, takes mod S k squared-- 1123 00:54:25,150 --> 00:54:25,870 oh, I'm sorry. 1124 00:54:25,870 --> 00:54:27,040 That was a lie. 1125 00:54:27,040 --> 00:54:30,524 If I actually multiply these things together, what I get 1126 00:54:30,524 --> 00:54:31,398 is-- sorry. 1127 00:54:31,398 --> 00:54:33,430 [LAUGHING] I need more sleep-- 1128 00:54:33,430 --> 00:54:35,440 S P k. 1129 00:54:35,440 --> 00:54:37,180 And that is against the rules. 1130 00:54:37,180 --> 00:54:40,740 So that's frowny face, yeah. 1131 00:54:40,740 --> 00:54:43,540 Because in particular, I took two big numbers, in some sense, 1132 00:54:43,540 --> 00:54:47,350 and multiplied them together, and that's not good. 1133 00:54:47,350 --> 00:54:50,100 So what is a person to do? 1134 00:54:50,100 --> 00:54:51,480 I tried to solve my problem. 1135 00:54:51,480 --> 00:54:54,000 I came up with-- by the way, from a partial credit 1136 00:54:54,000 --> 00:54:56,220 perspective, I think you'd be doing OK 1137 00:54:56,220 --> 00:54:57,600 if you got to this point. 1138 00:54:57,600 --> 00:55:00,900 OK, not great, but OK. 1139 00:55:00,900 --> 00:55:03,210 But of course, the problem is asking 1140 00:55:03,210 --> 00:55:06,510 you to solve this is this funny runtime, which 1141 00:55:06,510 --> 00:55:11,500 is kP, plus k squared S. 1142 00:55:11,500 --> 00:55:13,220 When I see a sum like this-- 1143 00:55:13,220 --> 00:55:15,715 and remember that there are two problems to solve. 1144 00:55:15,715 --> 00:55:17,590 There are two strategies for solving problems 1145 00:55:17,590 --> 00:55:18,423 in algorithms class. 1146 00:55:18,423 --> 00:55:20,950 There's one which is useful in your everyday lives, which 1147 00:55:20,950 --> 00:55:22,690 is to devise algorithms. 1148 00:55:22,690 --> 00:55:24,940 There's a second, which is to psychologically diagnose 1149 00:55:24,940 --> 00:55:26,268 your instructors. 1150 00:55:26,268 --> 00:55:28,810 And I think that second strategy is actually pretty effective 1151 00:55:28,810 --> 00:55:29,310 here. 1152 00:55:29,310 --> 00:55:30,430 I see two terms. 1153 00:55:30,430 --> 00:55:32,088 Most of our dynamic programming things 1154 00:55:32,088 --> 00:55:33,880 involve filling in a table, where you would 1155 00:55:33,880 --> 00:55:35,840 expect there to be a product. 1156 00:55:35,840 --> 00:55:39,790 So in general, I would squint at this and think, like, hm, maybe 1157 00:55:39,790 --> 00:55:42,170 I have to do some pre-computation. 1158 00:55:42,170 --> 00:55:43,160 Yeah? 1159 00:55:43,160 --> 00:55:47,630 In particular, we've got to do a lot of string-matching 1160 00:55:47,630 --> 00:55:52,490 in our problem, and maybe we can make that more efficient. 1161 00:55:52,490 --> 00:55:53,020 Yeah? 1162 00:55:53,020 --> 00:55:56,690 That's sort of the main question here. 1163 00:55:56,690 --> 00:55:59,030 So this thing is too slow, and we're trying to fix it. 1164 00:55:59,030 --> 00:56:00,950 The way I'm going to try and fix it 1165 00:56:00,950 --> 00:56:05,422 is to say, like, OK, well, I have mod S sub-problems. 1166 00:56:05,422 --> 00:56:07,380 If I look at these two terms, how much work can 1167 00:56:07,380 --> 00:56:09,690 I actually do in my sub-problem, something 1168 00:56:09,690 --> 00:56:12,560 that looks like k squared, maybe plus this amount 1169 00:56:12,560 --> 00:56:13,540 of pre-computation. 1170 00:56:13,540 --> 00:56:15,040 See what I did there? 1171 00:56:15,040 --> 00:56:16,210 OK. 1172 00:56:16,210 --> 00:56:19,510 So let's do that. 1173 00:56:19,510 --> 00:56:21,410 So in particular, here are the types 1174 00:56:21,410 --> 00:56:23,160 of queries that I'm going to have to make. 1175 00:56:26,580 --> 00:56:29,580 There's a bunch of times in my code when-- 1176 00:56:29,580 --> 00:56:30,930 here's a number that-- 1177 00:56:30,930 --> 00:56:33,930 [HICCUPS] yikes, I'm falling apart. 1178 00:56:33,930 --> 00:56:36,750 That's what I get for sprinting across campus to get here. 1179 00:56:36,750 --> 00:56:41,280 I'm going to find a number m i, j. 1180 00:56:41,280 --> 00:56:47,835 And it's going to be 1 if the substring S i-- 1181 00:56:47,835 --> 00:56:57,741 oh, man-- to j is in my list of markers P, and 0 otherwise. 1182 00:57:00,900 --> 00:57:02,430 By the way, why is this enough? 1183 00:57:02,430 --> 00:57:05,070 Notice that I'm not answering, which marker? 1184 00:57:05,070 --> 00:57:07,300 But the problem doesn't really care, right? 1185 00:57:07,300 --> 00:57:09,330 This problem just checks if there is a marker. 1186 00:57:09,330 --> 00:57:11,988 And if so, then I use that, yeah. 1187 00:57:11,988 --> 00:57:13,530 So if I have this thing, that's going 1188 00:57:13,530 --> 00:57:15,438 to somehow make this for loop a heck of a lot 1189 00:57:15,438 --> 00:57:17,730 easier, because now I don't have to do string-matching. 1190 00:57:17,730 --> 00:57:19,810 We'll return to that in a minute. 1191 00:57:19,810 --> 00:57:21,340 OK. 1192 00:57:21,340 --> 00:57:24,790 So my question is, how can I compute this thing? 1193 00:57:24,790 --> 00:57:30,030 And by the way, notice that I know 1194 00:57:30,030 --> 00:57:33,060 how to compute this when the difference between i and j 1195 00:57:33,060 --> 00:57:36,870 is bigger than k, because I know that all of my markers 1196 00:57:36,870 --> 00:57:38,510 have length k or less. 1197 00:57:38,510 --> 00:57:40,260 That's going to be important, because even 1198 00:57:40,260 --> 00:57:44,980 though m is doubly indexed, I don't actually need to do that. 1199 00:57:44,980 --> 00:57:47,543 In fact, I could even store it using less memory 1200 00:57:47,543 --> 00:57:48,960 than that, if I wanted to, by just 1201 00:57:48,960 --> 00:57:51,240 storing that diagonal block. 1202 00:57:51,240 --> 00:57:54,855 OK, right. 1203 00:57:54,855 --> 00:57:56,230 So the other thing, which I think 1204 00:57:56,230 --> 00:57:58,180 we saw in a previous problem session, as well, 1205 00:57:58,180 --> 00:58:00,013 is that when we do a lot of string-matching, 1206 00:58:00,013 --> 00:58:03,670 it often pays to put our strings into a hash table, 1207 00:58:03,670 --> 00:58:05,500 so that they're easier to look up later. 1208 00:58:05,500 --> 00:58:08,040 Does this string exist in this thing or not? 1209 00:58:08,040 --> 00:58:11,210 Rather than matching every character every single time. 1210 00:58:11,210 --> 00:58:14,836 So maybe we do that, just for fun. 1211 00:58:14,836 --> 00:58:17,272 And in general, when you see a string-matching problem-- 1212 00:58:17,272 --> 00:58:18,730 and you have a list of strings, I'd 1213 00:58:18,730 --> 00:58:20,188 suggest thinking about hash tables, 1214 00:58:20,188 --> 00:58:21,960 just for fun and profit. 1215 00:58:21,960 --> 00:58:27,520 So in step one here, maybe I put all the strings in P 1216 00:58:27,520 --> 00:58:28,150 into a hash. 1217 00:58:32,420 --> 00:58:33,782 OK? 1218 00:58:33,782 --> 00:58:34,990 How much time does that take? 1219 00:58:34,990 --> 00:58:39,207 Well, I have to process every string, find its code, 1220 00:58:39,207 --> 00:58:40,790 which is going to take more of k time. 1221 00:58:40,790 --> 00:58:46,880 There's mod P of them, so this is k mod P time. 1222 00:58:46,880 --> 00:58:49,550 Notice that that conveniently agrees with our first term 1223 00:58:49,550 --> 00:58:50,050 here. 1224 00:58:50,050 --> 00:58:52,410 So we feel like, aha, we're in good shape. 1225 00:58:52,410 --> 00:58:54,710 We're making progress here. 1226 00:58:54,710 --> 00:59:01,130 And now, maybe I want to fill in this m, i, j objects here. 1227 00:59:01,130 --> 00:59:04,050 How could I do that? 1228 00:59:04,050 --> 00:59:07,250 Well, for one, I'm certainly going to iterate over all 1229 00:59:07,250 --> 00:59:08,220 possible i's. 1230 00:59:08,220 --> 00:59:08,720 OK? 1231 00:59:08,720 --> 00:59:10,530 So let's do that. 1232 00:59:10,530 --> 00:59:12,410 So we're going to do 2. 1233 00:59:12,410 --> 00:59:15,162 By the way, I'm using 1's and 2's and a's and b's 1234 00:59:15,162 --> 00:59:15,870 and the whatever. 1235 00:59:15,870 --> 00:59:18,230 These are just ways to denote steps of things. 1236 00:59:18,230 --> 00:59:24,330 [LAUGHING] OK, so let's say that I just 1237 00:59:24,330 --> 00:59:27,690 want to fill in m using a brain-dead algorithm. 1238 00:59:27,690 --> 00:59:33,350 So I could go from 1 to the size of my strings for i. 1239 00:59:33,350 --> 00:59:33,950 Careful. 1240 00:59:33,950 --> 00:59:37,070 Now I can't incur an S squared. 1241 00:59:37,070 --> 00:59:40,770 But I know that my strings are always at mostly k. 1242 00:59:40,770 --> 00:59:51,900 So I could do for j equals i plus 1 to i plus k. 1243 00:59:51,900 --> 00:59:56,050 So this for loop actually incurs k time, not mod S time. 1244 00:59:56,050 --> 00:59:58,450 And now I can do two things. 1245 00:59:58,450 --> 01:00:06,270 I can find the hash of the string from i to j. 1246 01:00:06,270 --> 01:00:10,470 This is going to take order k time. 1247 01:00:10,470 --> 01:00:15,250 And I can search for it-- 1248 01:00:15,250 --> 01:00:29,360 ah, no-- to see if it's actually in our hash table of P. 1249 01:00:29,360 --> 01:00:31,760 And if it is, then I set m equal to 1. 1250 01:00:31,760 --> 01:00:33,440 Otherwise, I set m equal to 0. 1251 01:00:37,700 --> 01:00:39,890 And these are constant time operations, 1252 01:00:39,890 --> 01:00:41,630 at least in expectation. 1253 01:00:41,630 --> 01:00:43,710 So how much cost to it? 1254 01:00:43,710 --> 01:00:47,135 And so this, you can convince yourself fills in that array m. 1255 01:00:47,135 --> 01:00:48,260 How much time does it take? 1256 01:00:48,260 --> 01:00:53,900 Well, I have a loop to the size of S. I have a loop of size k. 1257 01:00:53,900 --> 01:00:57,460 I have a second loop of size k here to compute the hash. 1258 01:00:57,460 --> 01:01:01,885 So this whole thing is going to take order k squared mod 1259 01:01:01,885 --> 01:01:04,540 S time, like that. 1260 01:01:04,540 --> 01:01:08,390 Now, this conveniently-- there's chalk on the floor. 1261 01:01:08,390 --> 01:01:11,180 And this is the second term in our runtime. 1262 01:01:11,180 --> 01:01:12,140 So this is kosher. 1263 01:01:12,140 --> 01:01:13,370 We can fill in m. 1264 01:01:13,370 --> 01:01:16,700 And that's a convenient object to have around. 1265 01:01:16,700 --> 01:01:18,290 So the only thing that remains is 1266 01:01:18,290 --> 01:01:24,170 to revise our R from above, to make use of the m that we have. 1267 01:01:24,170 --> 01:01:25,978 And that's pretty straightforward. 1268 01:01:30,560 --> 01:01:33,310 So the trick is to not lean against this thing 1269 01:01:33,310 --> 01:01:34,970 and to actually hit the stop button. 1270 01:01:34,970 --> 01:01:36,230 I'm learning. 1271 01:01:36,230 --> 01:01:43,350 So now I suppose we had T2 for the second T. So for revised R, 1272 01:01:43,350 --> 01:01:46,008 we should have R prime. 1273 01:01:46,008 --> 01:01:47,872 [LAUGHING] 1274 01:01:47,872 --> 01:01:48,810 AUDIENCE: [INAUDIBLE] 1275 01:01:48,810 --> 01:01:49,290 JUSTIN SOLOMON: What was that? 1276 01:01:49,290 --> 01:01:50,910 AUDIENCE: The deriviative. 1277 01:01:50,910 --> 01:01:51,270 JUSTIN SOLOMON: That's right. 1278 01:01:51,270 --> 01:01:53,820 The derivative-- yeah, we could do Christoffel symbols, 1279 01:01:53,820 --> 01:01:56,210 like i, j prime, and semicolon k. 1280 01:01:59,100 --> 01:02:04,740 Take 6838 if you want to learn what Christoffel symbols are. 1281 01:02:04,740 --> 01:02:10,500 Right, so now, what is my recursive call for xi? 1282 01:02:10,500 --> 01:02:12,360 Well, I want to maximize. 1283 01:02:15,310 --> 01:02:16,430 Well, what can I do? 1284 01:02:16,430 --> 01:02:18,130 I can check every possible length 1285 01:02:18,130 --> 01:02:22,450 of a string that could be in P, check 1286 01:02:22,450 --> 01:02:27,570 if it is, using my array m, and get that amount of profit. 1287 01:02:27,570 --> 01:02:30,043 So in particular, I get m. 1288 01:02:30,043 --> 01:02:31,960 By the way, I keep using the word profit here. 1289 01:02:31,960 --> 01:02:34,390 I am essentially using that to mean increment 1290 01:02:34,390 --> 01:02:36,160 in every single one of our problems here. 1291 01:02:36,160 --> 01:02:38,650 I like to think of our problems as maximizing profit, 1292 01:02:38,650 --> 01:02:40,270 because I'm a greedy professor. 1293 01:02:40,270 --> 01:02:45,370 So this is m, i j, which would be 1 if I found a string there 1294 01:02:45,370 --> 01:02:52,510 and 0 if I'm not, plus xi plus j, to account for the length 1295 01:02:52,510 --> 01:02:58,300 here, where j is in 1 to-- 1296 01:02:58,300 --> 01:03:02,200 well, either the length of the string, 1297 01:03:02,200 --> 01:03:04,090 or I get to the end of-- 1298 01:03:04,090 --> 01:03:06,310 either the maximum length of a string in P, 1299 01:03:06,310 --> 01:03:11,220 or I get to the end of my array, like that. 1300 01:03:11,220 --> 01:03:11,720 OK. 1301 01:03:11,720 --> 01:03:13,440 And this is our new recursive call. 1302 01:03:13,440 --> 01:03:14,940 The one thing we should double-check 1303 01:03:14,940 --> 01:03:18,120 is, what is the runtime for actually filling in x now? 1304 01:03:18,120 --> 01:03:22,270 Well, there's still the mod S sub-problems. 1305 01:03:22,270 --> 01:03:24,950 And now how long does it take? 1306 01:03:24,950 --> 01:03:27,820 Well, now I just have one loop over k things. 1307 01:03:27,820 --> 01:03:29,680 This is mod S times k. 1308 01:03:29,680 --> 01:03:31,780 It's actually less than any of the terms that's 1309 01:03:31,780 --> 01:03:34,460 in our runtime. 1310 01:03:34,460 --> 01:03:35,410 And so this is fine. 1311 01:03:35,410 --> 01:03:37,570 This actually is kind of a funny example, 1312 01:03:37,570 --> 01:03:41,170 where the dynamic programming part of our algorithm, 1313 01:03:41,170 --> 01:03:43,330 once we've done all this cute pre-computation, 1314 01:03:43,330 --> 01:03:46,240 is actually insignificant, compared to all 1315 01:03:46,240 --> 01:03:49,240 the pre-computation that we had to do in our final runtime-- 1316 01:03:49,240 --> 01:03:51,120 sneaky. 1317 01:03:51,120 --> 01:03:53,550 All right, any questions about protein folding, 1318 01:03:53,550 --> 01:03:55,710 or whatever it is that we just did? 1319 01:03:55,710 --> 01:03:57,030 OK. 1320 01:03:57,030 --> 01:03:58,480 So as usual, I'm talking too much. 1321 01:03:58,480 --> 01:03:59,520 AUDIENCE: [INAUDIBLE]? 1322 01:03:59,520 --> 01:04:01,050 JUSTIN SOLOMON: Yeah, which one would you prefer to cut? 1323 01:04:01,050 --> 01:04:01,990 AUDIENCE: [INAUDIBLE] 1324 01:04:01,990 --> 01:04:06,690 JUSTIN SOLOMON: I have very few preferences. 1325 01:04:06,690 --> 01:04:09,150 OK, so one of your problems-- 1326 01:04:09,150 --> 01:04:12,210 I would take a vote, but with our audience, 1327 01:04:12,210 --> 01:04:16,390 there's is a high probability of a split on jury here. 1328 01:04:16,390 --> 01:04:16,890 Right. 1329 01:04:16,890 --> 01:04:18,000 So there's two remaining problems 1330 01:04:18,000 --> 01:04:18,958 on the problem session. 1331 01:04:18,958 --> 01:04:20,940 As usual, your instructor-- 1332 01:04:20,940 --> 01:04:21,895 AUDIENCE: [INAUDIBLE] 1333 01:04:21,895 --> 01:04:23,520 JUSTIN SOLOMON: You can leave it there. 1334 01:04:23,520 --> 01:04:27,000 This is another problem to learn about. 1335 01:04:27,000 --> 01:04:30,210 As usual, I've talked too much and haven't got to the end. 1336 01:04:30,210 --> 01:04:33,030 I get the impression that in 6006, this egg drop thing 1337 01:04:33,030 --> 01:04:35,193 is a bit of a tradition anyway. 1338 01:04:35,193 --> 01:04:37,110 So maybe we'll cover that problem really fast. 1339 01:04:37,110 --> 01:04:39,060 Do they do that in section, some variation? 1340 01:04:39,060 --> 01:04:39,360 AUDIENCE: No. 1341 01:04:39,360 --> 01:04:40,652 JUSTIN SOLOMON: Not this time-- 1342 01:04:40,652 --> 01:04:41,890 even better. 1343 01:04:41,890 --> 01:04:44,977 OK, so yes, so maybe we'll do this egg-drop thing, 1344 01:04:44,977 --> 01:04:46,560 mostly because the other one, I think, 1345 01:04:46,560 --> 01:04:48,840 takes a lot of verbal setup. 1346 01:04:48,840 --> 01:04:51,570 The other one is-- 1347 01:04:51,570 --> 01:04:54,180 I would say, from a dynamic programming perspective, maybe 1348 01:04:54,180 --> 01:04:55,140 not super exciting. 1349 01:04:55,140 --> 01:04:57,690 But from an interesting problem perspective, 1350 01:04:57,690 --> 01:05:00,380 it's kind of cool to think about. 1351 01:05:00,380 --> 01:05:02,130 So I'd encourage you to leave it in there, 1352 01:05:02,130 --> 01:05:04,830 and you guys can read it at home. 1353 01:05:04,830 --> 01:05:06,920 From a coding perspective, it's also kind of fun. 1354 01:05:06,920 --> 01:05:08,920 I notice the solution didn't do what I would do, 1355 01:05:08,920 --> 01:05:11,800 which would be to use the bits in the-- 1356 01:05:11,800 --> 01:05:13,530 assume that something wasn't too tall, 1357 01:05:13,530 --> 01:05:18,080 use the bits in an integer to store your binary variables. 1358 01:05:18,080 --> 01:05:19,520 But that's an old hack. 1359 01:05:19,520 --> 01:05:21,803 That's like this old hack for computing 1360 01:05:21,803 --> 01:05:23,720 the square root of a number, that's apparently 1361 01:05:23,720 --> 01:05:27,260 in the code for the Doom video game, which involves 1362 01:05:27,260 --> 01:05:30,140 bit-shifting, and it happens to agree with square root, 1363 01:05:30,140 --> 01:05:35,000 for some magic reason, that numerical analysts really hate. 1364 01:05:35,000 --> 01:05:38,940 OK, so let's do lazy egg drop instead. 1365 01:05:38,940 --> 01:05:41,420 So that's problem 4. 1366 01:05:41,420 --> 01:05:43,820 OK. 1367 01:05:43,820 --> 01:05:46,000 So we're in a building. 1368 01:05:46,000 --> 01:05:51,690 Our building has n floors and k eggs. 1369 01:05:54,212 --> 01:05:56,170 I guess it's debatable whether the building has 1370 01:05:56,170 --> 01:05:58,780 eggs or the residents-- but in any event, 1371 01:05:58,780 --> 01:06:01,000 have some set of eggs. 1372 01:06:01,000 --> 01:06:02,530 And maybe I'm in this data center 1373 01:06:02,530 --> 01:06:03,740 or some other weird building. 1374 01:06:03,740 --> 01:06:08,470 So I don't have heights of floors that are isotropic, 1375 01:06:08,470 --> 01:06:10,972 but rather, each floor has a different height, 1376 01:06:10,972 --> 01:06:11,680 which could vary. 1377 01:06:15,040 --> 01:06:20,060 So it's height of floor, or i. 1378 01:06:20,060 --> 01:06:24,650 I really want to write flour, but I digress. 1379 01:06:24,650 --> 01:06:28,753 And we're going to assume that our list is already sorted. 1380 01:06:28,753 --> 01:06:30,170 So in other words, the fifth floor 1381 01:06:30,170 --> 01:06:32,330 is taller than the fourth floor, and we 1382 01:06:32,330 --> 01:06:36,710 don't have to spend n log-in time doing that. 1383 01:06:36,710 --> 01:06:37,770 OK. 1384 01:06:37,770 --> 01:06:38,270 Right. 1385 01:06:38,270 --> 01:06:42,410 So apparently, in our problem, we 1386 01:06:42,410 --> 01:06:44,810 have an egg with a mysterious mechanical property 1387 01:06:44,810 --> 01:06:47,900 that we are trying to recover. 1388 01:06:47,900 --> 01:06:51,260 And all eggs, as we know, are identical. 1389 01:06:51,260 --> 01:06:54,830 So the only difference between eggs is chicken, versus goose, 1390 01:06:54,830 --> 01:06:55,940 versus-- 1391 01:06:55,940 --> 01:06:58,860 I'm struggling to think of a third category of poultry-- 1392 01:06:58,860 --> 01:06:59,360 turkey. 1393 01:06:59,360 --> 01:07:01,640 Thank you. 1394 01:07:01,640 --> 01:07:03,518 But assuming that I got all of my eggs 1395 01:07:03,518 --> 01:07:05,060 at the same Stop-N-Shop, and they all 1396 01:07:05,060 --> 01:07:06,770 come from the same species, then they 1397 01:07:06,770 --> 01:07:08,930 have roughly the same mechanical properties. 1398 01:07:08,930 --> 01:07:10,400 Actually, probably the better setup 1399 01:07:10,400 --> 01:07:12,150 is that floors are very far apart relative 1400 01:07:12,150 --> 01:07:14,990 to the size of an egg. 1401 01:07:14,990 --> 01:07:17,690 And if I get high enough, my egg, 1402 01:07:17,690 --> 01:07:22,998 when I drop them on the ground, like that, breaks. 1403 01:07:22,998 --> 01:07:23,540 Didn't break. 1404 01:07:23,540 --> 01:07:25,100 But it could have broken. 1405 01:07:25,100 --> 01:07:28,310 And of course, if I drop it from an even higher height, 1406 01:07:28,310 --> 01:07:30,860 my egg still is going to break. 1407 01:07:30,860 --> 01:07:33,050 However, if I have a very low floor-- apparently, 1408 01:07:33,050 --> 01:07:33,800 a very low floor. 1409 01:07:33,800 --> 01:07:37,490 Maybe this is a house for mice. 1410 01:07:37,490 --> 01:07:40,280 And I drop my egg, it actually stays intact. 1411 01:07:40,280 --> 01:07:43,790 And the question, as all good scientists want to know, 1412 01:07:43,790 --> 01:07:46,760 is, what is the highest floor in my building from which I 1413 01:07:46,760 --> 01:07:51,460 can drop an egg and have it remain intact? 1414 01:07:51,460 --> 01:07:56,500 And the question is kind of a funny one. 1415 01:07:56,500 --> 01:07:59,460 It's sort of like experimental design, in some sense. 1416 01:07:59,460 --> 01:08:05,130 It's not asking, given this and a list of experiments, try 1417 01:08:05,130 --> 01:08:07,500 and figure, infer, something about the eggs. 1418 01:08:07,500 --> 01:08:10,830 But rather, it's saying, if I carefully 1419 01:08:10,830 --> 01:08:15,560 design a sequence of floors to drop my eggs from, 1420 01:08:15,560 --> 01:08:22,170 from which upon I drop my eggs, then 1421 01:08:22,170 --> 01:08:24,630 what is the maximum number of experiments 1422 01:08:24,630 --> 01:08:28,380 I need to do to triangulate in on that floor, 1423 01:08:28,380 --> 01:08:32,770 that critical floor, above which my eggs break? 1424 01:08:32,770 --> 01:08:34,920 So what I'm given are the heights of the floors 1425 01:08:34,920 --> 01:08:36,340 and a bunch of eggs. 1426 01:08:36,340 --> 01:08:39,609 In some sense, the budget of eggs 1427 01:08:39,609 --> 01:08:42,819 doesn't matter more than just putting a cap on the size 1428 01:08:42,819 --> 01:08:44,750 of our problem, in some sense. 1429 01:08:44,750 --> 01:08:47,109 What really matters is I'd like to use fewer than k eggs 1430 01:08:47,109 --> 01:08:48,147 to determine that. 1431 01:08:48,147 --> 01:08:49,689 Because of course, the remaining ones 1432 01:08:49,689 --> 01:08:52,609 I'm going to use to make an omelet. 1433 01:08:52,609 --> 01:08:54,410 But notice that I can be a little 1434 01:08:54,410 --> 01:08:58,219 sneaky in my experimental design, 1435 01:08:58,219 --> 01:09:02,279 that what happens if I drop my egg from a really 1436 01:09:02,279 --> 01:09:04,620 low floor in my building? 1437 01:09:04,620 --> 01:09:06,790 Well, it remains intact. 1438 01:09:06,790 --> 01:09:09,310 So I can schlep down the stairs. 1439 01:09:09,310 --> 01:09:11,910 I can pick up my egg, and I can use it for my next experiment. 1440 01:09:11,910 --> 01:09:15,520 And I have not paid an egg. 1441 01:09:15,520 --> 01:09:17,710 Yeah? 1442 01:09:17,710 --> 01:09:19,390 So the first question you might ask 1443 01:09:19,390 --> 01:09:22,520 is, like, well, why the heck wouldn't I just 1444 01:09:22,520 --> 01:09:24,510 start on the first floor, drop the egg. 1445 01:09:24,510 --> 01:09:27,625 If it's not broken, go on to the next one 1446 01:09:27,625 --> 01:09:29,000 and then drop the egg, and so on? 1447 01:09:29,000 --> 01:09:32,040 That would be the most egg-efficient plan. 1448 01:09:32,040 --> 01:09:34,040 And indeed that is the case, because you'll only 1449 01:09:34,040 --> 01:09:35,960 break at most one egg. 1450 01:09:35,960 --> 01:09:38,297 But you're schlepping up and down the stairs 1451 01:09:38,297 --> 01:09:40,130 a bunch of times when you solve that, right? 1452 01:09:40,130 --> 01:09:44,353 Every single time, you've got to go retrieve that unbroken egg. 1453 01:09:44,353 --> 01:09:45,770 You've got to run down the stairs, 1454 01:09:45,770 --> 01:09:47,978 pick the thing up, and then run up to the next floor. 1455 01:09:47,978 --> 01:09:50,540 And maybe in your optimization problem, 1456 01:09:50,540 --> 01:09:52,830 rather than trying to minimize the number of eggs 1457 01:09:52,830 --> 01:09:56,600 that you break, you're trying to minimize the expense 1458 01:09:56,600 --> 01:09:57,800 on your quads. 1459 01:09:57,800 --> 01:10:03,020 And so instead, you've skipped your leg day, or whatever, 1460 01:10:03,020 --> 01:10:05,630 and the thing that you're trying to minimize 1461 01:10:05,630 --> 01:10:14,600 is the sum over the heights of the drops in your experiments. 1462 01:10:14,600 --> 01:10:18,340 So you're trying to determine the mechanical property 1463 01:10:18,340 --> 01:10:21,580 of your egg by designing an experiment, sort 1464 01:10:21,580 --> 01:10:24,340 of a procedure, that minimizes the number of times 1465 01:10:24,340 --> 01:10:26,325 that you need to drop eggs. 1466 01:10:26,325 --> 01:10:27,700 Because every time you do, you've 1467 01:10:27,700 --> 01:10:29,080 got to run all the way back down the stairs, 1468 01:10:29,080 --> 01:10:31,622 and go look at the pavement, and see if the egg broke or not. 1469 01:10:31,622 --> 01:10:32,620 That's a lot of work. 1470 01:10:32,620 --> 01:10:33,610 OK. 1471 01:10:33,610 --> 01:10:36,910 This is different from the classic egg-drop 6006 problem, 1472 01:10:36,910 --> 01:10:38,980 which I encourage you guys to go seek out, 1473 01:10:38,980 --> 01:10:42,310 in previous iterations of this course. 1474 01:10:42,310 --> 01:10:44,680 Let me see. 1475 01:10:44,680 --> 01:10:50,170 And so the question is, what is the minimum number of egg drops 1476 01:10:50,170 --> 01:10:54,610 you need to do to ascertain that for any type of egg-- 1477 01:10:54,610 --> 01:10:56,740 so I give you a mystery basket of eggs, 1478 01:10:56,740 --> 01:10:59,230 and you have to design the experimental procedure 1479 01:10:59,230 --> 01:11:03,280 and bound the number of this particular value here, 1480 01:11:03,280 --> 01:11:05,830 given a budget of k eggs. 1481 01:11:05,830 --> 01:11:07,030 OK. 1482 01:11:07,030 --> 01:11:13,690 And the amount of time that we have to do that is order n 1483 01:11:13,690 --> 01:11:16,070 cubed k. 1484 01:11:16,070 --> 01:11:18,020 Apparently, our building, we have 1485 01:11:18,020 --> 01:11:20,760 lots of eggs and not very many floors. 1486 01:11:20,760 --> 01:11:21,860 OK. 1487 01:11:21,860 --> 01:11:23,563 Does our setup make some sense here? 1488 01:11:23,563 --> 01:11:25,980 We're just trying to avoid running up and down the stairs. 1489 01:11:25,980 --> 01:11:28,070 That's the main takeaway. 1490 01:11:28,070 --> 01:11:29,930 OK. 1491 01:11:29,930 --> 01:11:31,730 So what are we going to do? 1492 01:11:31,730 --> 01:11:34,430 SRTBOT, because that's all we know how to do, yeah? 1493 01:11:34,430 --> 01:11:37,550 And in particular, we're going to make one observation, which 1494 01:11:37,550 --> 01:11:38,810 is kind of handy. 1495 01:11:38,810 --> 01:11:40,900 If I drop a floor-- 1496 01:11:40,900 --> 01:11:45,600 ooh, if I drop an egg from a floor, 1497 01:11:45,600 --> 01:11:49,290 in this deterministic universe, where egg mechanics are 1498 01:11:49,290 --> 01:11:51,850 very predictable, there's only one 1499 01:11:51,850 --> 01:11:53,100 of two things that can happen. 1500 01:11:53,100 --> 01:11:56,310 Either the egg broke or it didn't, 1501 01:11:56,310 --> 01:11:58,900 while I run into the board again. 1502 01:11:58,900 --> 01:12:01,467 So let's think about our experiment. 1503 01:12:01,467 --> 01:12:03,050 Remember, at the end of the day, we're 1504 01:12:03,050 --> 01:12:07,340 trying to figure out the tallest floor in my building 1505 01:12:07,340 --> 01:12:10,910 from which I can safely drop an egg. 1506 01:12:10,910 --> 01:12:17,095 So if I think about bracketing that height of that floor, 1507 01:12:17,095 --> 01:12:18,720 for one thing, do I ever need a bracket 1508 01:12:18,720 --> 01:12:23,370 that's not a continuous or a connected set of numbers? 1509 01:12:23,370 --> 01:12:24,420 The answer is no, right? 1510 01:12:24,420 --> 01:12:26,782 It should never be the case that, like, oh, 1511 01:12:26,782 --> 01:12:29,588 I think that my eggs could be on floors one-- 1512 01:12:29,588 --> 01:12:32,130 only the prime number of floors in my building, or something. 1513 01:12:32,130 --> 01:12:33,547 That really makes no sense, right? 1514 01:12:33,547 --> 01:12:36,900 Because if I convince myself my egg breaks at four or five, 1515 01:12:36,900 --> 01:12:40,270 then obviously, floors six through n, my egg also breaks. 1516 01:12:40,270 --> 01:12:44,610 And so I always can just keep narrowing down some interval. 1517 01:12:44,610 --> 01:12:45,660 Right? 1518 01:12:45,660 --> 01:12:49,020 So in particular, here's a clever S 1519 01:12:49,020 --> 01:12:53,960 in my SRTBOT, which is to say that I'm 1520 01:12:53,960 --> 01:13:04,060 going to say that x, i, j, e is equal to the minimum-- 1521 01:13:04,060 --> 01:13:07,288 by the way, I'm writing this as minimum total height. 1522 01:13:07,288 --> 01:13:09,580 So this is the minimum total times I've got to run down 1523 01:13:09,580 --> 01:13:13,360 the stairs and check my eggs, or total height that I run down 1524 01:13:13,360 --> 01:13:17,200 the stair-- the number of stairs I run down, 1525 01:13:17,200 --> 01:13:21,160 assuming my stairs are 1 foot tall-- 1526 01:13:21,160 --> 01:13:24,220 where I have e eggs left. 1527 01:13:26,827 --> 01:13:29,160 Notice the way that we've written the problem this time, 1528 01:13:29,160 --> 01:13:31,150 I might as well use all of my k eggs. 1529 01:13:31,150 --> 01:13:32,400 That doesn't cost me anything. 1530 01:13:32,400 --> 01:13:35,970 What costs me is running up and down the stairs. 1531 01:13:35,970 --> 01:13:44,610 And that I have floors i through j inclusive to check. 1532 01:13:44,610 --> 01:13:47,070 So in other words, if I'm on a floor below floor i, 1533 01:13:47,070 --> 01:13:49,380 I've convinced myself my egg won't break. 1534 01:13:49,380 --> 01:13:51,480 But if I'm on a a floor above floor j, 1535 01:13:51,480 --> 01:13:54,130 I'm convinced my egg will break. 1536 01:13:54,130 --> 01:13:55,090 OK? 1537 01:13:55,090 --> 01:13:57,560 So what do I do? 1538 01:13:57,560 --> 01:14:00,400 Well, remember that this is an experimental design problem. 1539 01:14:00,400 --> 01:14:14,110 I can drop my egg from any floor f, which is in the range i 1540 01:14:14,110 --> 01:14:15,607 to j. 1541 01:14:15,607 --> 01:14:17,440 And of course, there's never a reason for me 1542 01:14:17,440 --> 01:14:20,350 to drop an egg from a floor below i or above j, 1543 01:14:20,350 --> 01:14:22,900 because we already know what happens in that case. 1544 01:14:22,900 --> 01:14:24,700 OK? 1545 01:14:24,700 --> 01:14:29,320 So what happens when we do that? 1546 01:14:29,320 --> 01:14:31,950 Well, if I drop it from floor f, I 1547 01:14:31,950 --> 01:14:34,980 have to pay, in terms of my cost function, right? 1548 01:14:34,980 --> 01:14:39,300 Because to pay the height of f, I've got run down the stairs. 1549 01:14:39,300 --> 01:14:41,670 OK? 1550 01:14:41,670 --> 01:14:45,690 But in exchange for that, I learn a little bit 1551 01:14:45,690 --> 01:14:46,740 about my egg problem. 1552 01:14:46,740 --> 01:14:49,030 I either get an upper or a lower bound of f, 1553 01:14:49,030 --> 01:14:50,950 depending on whether the egg broke. 1554 01:14:50,950 --> 01:14:51,450 OK? 1555 01:14:51,450 --> 01:14:55,240 So let's formalize that mathematically. 1556 01:14:55,240 --> 01:14:59,916 So in particular, we have x i, j, e. 1557 01:15:02,720 --> 01:15:05,840 Well, what do I get to control in my life? 1558 01:15:05,840 --> 01:15:08,160 And what do I have to deal with? 1559 01:15:08,160 --> 01:15:09,910 Well, what I have to deal with is the fact 1560 01:15:09,910 --> 01:15:11,040 that I don't know what's going to happen to the egg. 1561 01:15:11,040 --> 01:15:11,665 It might break. 1562 01:15:11,665 --> 01:15:12,540 It might not. 1563 01:15:12,540 --> 01:15:13,040 Right? 1564 01:15:13,040 --> 01:15:15,020 And the egg might be an adversarial egg-- 1565 01:15:15,020 --> 01:15:17,090 it wants you to run up and down the stairs. 1566 01:15:17,090 --> 01:15:19,080 And I have to account for that. 1567 01:15:19,080 --> 01:15:22,070 But i and the egg's adversary need 1568 01:15:22,070 --> 01:15:24,660 to choose what floor I drop it from. 1569 01:15:24,660 --> 01:15:27,410 So remember, we saw an example. 1570 01:15:27,410 --> 01:15:29,778 I forget what, from class, where there was a game. 1571 01:15:29,778 --> 01:15:31,070 One guy was trying to minimize. 1572 01:15:31,070 --> 01:15:33,320 The other was trying to maximize. 1573 01:15:33,320 --> 01:15:38,000 In some sense, the egg is trying to maximize the amount of work 1574 01:15:38,000 --> 01:15:41,540 you have to do, running up and down the stairs to do 1575 01:15:41,540 --> 01:15:42,360 your experiment. 1576 01:15:42,360 --> 01:15:43,860 A better way to put it is that we're 1577 01:15:43,860 --> 01:15:45,680 trying to upper bound the amount of work 1578 01:15:45,680 --> 01:15:47,840 in your experimental procedure. 1579 01:15:47,840 --> 01:15:49,670 And I'm trying to design a procedure that 1580 01:15:49,670 --> 01:15:50,935 minimizes my work. 1581 01:15:50,935 --> 01:15:52,310 So let's say that I'm the player. 1582 01:15:52,310 --> 01:15:55,230 So I want to minimize. 1583 01:15:55,230 --> 01:16:00,530 And the decision that I get to make, the control that I have, 1584 01:16:00,530 --> 01:16:01,560 is what? 1585 01:16:01,560 --> 01:16:04,230 Well, it's what floor I choose. 1586 01:16:04,230 --> 01:16:06,212 So let's say I choose floor f. 1587 01:16:06,212 --> 01:16:07,670 Well, I have to go down the stairs. 1588 01:16:07,670 --> 01:16:09,672 So that takes me hf. 1589 01:16:09,672 --> 01:16:11,380 This was going up the stairs, is probably 1590 01:16:11,380 --> 01:16:13,940 what incurs the hf going down is nothing. 1591 01:16:13,940 --> 01:16:15,640 But I digress. 1592 01:16:15,640 --> 01:16:18,850 But now I still am not done. 1593 01:16:18,850 --> 01:16:21,790 I've narrowed it down into one of two cases, right? 1594 01:16:21,790 --> 01:16:24,415 Either f is my new lower bound or my new upper bound. 1595 01:16:24,415 --> 01:16:27,460 And I have to account for both of those in my recursion 1596 01:16:27,460 --> 01:16:30,160 and actually, the max of those two, in the sense 1597 01:16:30,160 --> 01:16:33,430 that I need, in every possible case, 1598 01:16:33,430 --> 01:16:35,620 that my egg drop experiment narrows down 1599 01:16:35,620 --> 01:16:39,280 my floor to a width of 0. 1600 01:16:39,280 --> 01:16:43,060 So in particular, this is a mini-max problem. 1601 01:16:43,060 --> 01:16:46,610 There's a max inside of of a min here. 1602 01:16:46,610 --> 01:16:50,720 So either the egg broke in my experiment or it didn't. 1603 01:16:50,720 --> 01:16:51,320 Right? 1604 01:16:51,320 --> 01:16:55,660 So if it did broke, then, well, what happened? 1605 01:16:55,660 --> 01:16:57,970 Well, let's see here. 1606 01:16:57,970 --> 01:17:01,312 If the egg broke, then I got an upper bound for my floor. 1607 01:17:01,312 --> 01:17:02,770 So my lower bound remains the same. 1608 01:17:02,770 --> 01:17:04,090 It's i. 1609 01:17:04,090 --> 01:17:09,390 My upper bound is f minus 1, because it broke on floor f. 1610 01:17:09,390 --> 01:17:12,420 Well, what happens to eggs when they break? 1611 01:17:12,420 --> 01:17:14,920 I can't drop them from floors again. 1612 01:17:14,920 --> 01:17:17,320 So I lost an egg. 1613 01:17:17,320 --> 01:17:19,200 OK? 1614 01:17:19,200 --> 01:17:24,540 So this is my egg broke. 1615 01:17:24,540 --> 01:17:25,470 OK? 1616 01:17:25,470 --> 01:17:27,830 Or my egg didn't break. 1617 01:17:27,830 --> 01:17:31,430 So in that case, well, if my egg did break, 1618 01:17:31,430 --> 01:17:34,280 now I have a lower bound. 1619 01:17:34,280 --> 01:17:37,940 So I'm only unclear about floors f plus 1. 1620 01:17:37,940 --> 01:17:40,370 But the upper bound didn't change. 1621 01:17:40,370 --> 01:17:42,420 It's still j. 1622 01:17:42,420 --> 01:17:43,587 And how many eggs do I have? 1623 01:17:43,587 --> 01:17:45,420 Well, my egg didn't break, so I can run down 1624 01:17:45,420 --> 01:17:47,250 the stairs, which is going to be tiring, 1625 01:17:47,250 --> 01:17:48,665 I've accounted for that here. 1626 01:17:48,665 --> 01:17:50,040 But at least I can re-use my egg. 1627 01:17:50,040 --> 01:17:52,860 So I didn't lose anything. 1628 01:17:52,860 --> 01:17:54,490 OK? 1629 01:17:54,490 --> 01:17:57,830 And I get to choose. 1630 01:17:57,830 --> 01:18:01,030 So notice-- oops-- so do you guys 1631 01:18:01,030 --> 01:18:02,240 see why there's a max here? 1632 01:18:02,240 --> 01:18:05,470 Essentially, I have to account for every possible scenario 1633 01:18:05,470 --> 01:18:09,130 when I'm designing my experimental procedure. 1634 01:18:09,130 --> 01:18:10,728 But I get to minimize, in the sense 1635 01:18:10,728 --> 01:18:12,520 that I can choose what floor at every step. 1636 01:18:12,520 --> 01:18:23,810 So in particular, my f here is in the range i to j, like that. 1637 01:18:23,810 --> 01:18:25,670 OK, and now we have our recursive formula 1638 01:18:25,670 --> 01:18:29,400 for our egg drop that minimizes total height. 1639 01:18:29,400 --> 01:18:32,000 So now let's finish off SRTBOT in four minutes. 1640 01:18:32,000 --> 01:18:33,570 It's actually not too hard. 1641 01:18:33,570 --> 01:18:34,945 So I think we'll actually make it 1642 01:18:34,945 --> 01:18:37,960 for once by removing 20% of the problems I 1643 01:18:37,960 --> 01:18:40,910 was supposed to cover. 1644 01:18:40,910 --> 01:18:41,410 All right. 1645 01:18:47,420 --> 01:18:51,710 So first of all, what's our topological order? 1646 01:18:51,710 --> 01:18:57,460 So this one seems kind of annoying. 1647 01:18:57,460 --> 01:19:00,550 Because I think usually, we think 1648 01:19:00,550 --> 01:19:04,730 of spending stuff in a lot of these dynamic programming 1649 01:19:04,730 --> 01:19:05,230 problems. 1650 01:19:05,230 --> 01:19:06,563 But do we actually spend an egg? 1651 01:19:06,563 --> 01:19:07,720 Not necessarily, right? 1652 01:19:07,720 --> 01:19:12,910 Because in this recursive call, the number of eggs 1653 01:19:12,910 --> 01:19:14,090 I had remained the same. 1654 01:19:14,090 --> 01:19:16,780 So maybe that's not actually a great way to establish 1655 01:19:16,780 --> 01:19:18,400 a topological order. 1656 01:19:18,400 --> 01:19:20,500 But instead, what do we know? 1657 01:19:20,500 --> 01:19:24,040 What is in science the purpose of an experiment? 1658 01:19:24,040 --> 01:19:27,290 It's to improve our understanding of the world. 1659 01:19:27,290 --> 01:19:29,500 In this case, our world consists only 1660 01:19:29,500 --> 01:19:31,583 of eggs and floors of buildings. 1661 01:19:31,583 --> 01:19:33,250 And in particular, once I drop that egg, 1662 01:19:33,250 --> 01:19:34,750 I learn something about my building. 1663 01:19:34,750 --> 01:19:37,300 And I narrowed down the range of floors 1664 01:19:37,300 --> 01:19:38,830 that are uncertain for me. 1665 01:19:38,830 --> 01:19:43,548 So in particular, I know that x i, 1666 01:19:43,548 --> 01:19:57,200 j, e only depends on x, I guess, i prime, j prime, e prime, 1667 01:19:57,200 --> 01:19:58,520 with what? 1668 01:19:58,520 --> 01:20:01,550 Well, my sub-problems, I always have a smaller range of flaws 1669 01:20:01,550 --> 01:20:02,880 than I did before. 1670 01:20:02,880 --> 01:20:06,320 So in particular, j prime minus i 1671 01:20:06,320 --> 01:20:10,970 prime is going to be smaller strictly than j minus i. 1672 01:20:10,970 --> 01:20:15,450 And that'll give me my topological order. 1673 01:20:15,450 --> 01:20:16,420 Cool. 1674 01:20:16,420 --> 01:20:19,180 And so that's actually, I think, the sort of annoying part, 1675 01:20:19,180 --> 01:20:21,940 other than working out this mini-max expression here. 1676 01:20:21,940 --> 01:20:24,560 The remaining things are not so hard. 1677 01:20:24,560 --> 01:20:26,800 So what are our base cases? 1678 01:20:26,800 --> 01:20:31,970 Well, let's say I have 0 eggs left. 1679 01:20:31,970 --> 01:20:34,460 But I still have a set of uncertain floors. 1680 01:20:34,460 --> 01:20:36,410 That's bad news. 1681 01:20:36,410 --> 01:20:38,120 Yeah? 1682 01:20:38,120 --> 01:20:42,210 Yeah, so that should be infinity. 1683 01:20:42,210 --> 01:20:47,960 And the reason is, of course, I'm going to take the min here. 1684 01:20:47,960 --> 01:20:48,500 Right? 1685 01:20:48,500 --> 01:20:51,877 And so obviously, I should never choose infinity as a min. 1686 01:20:51,877 --> 01:20:53,960 So in other words, I should never choose an option 1687 01:20:53,960 --> 01:20:56,180 for a floor that could possibly lead me 1688 01:20:56,180 --> 01:21:01,550 to an uncertain scenario, when I run out of eggs, yeah? 1689 01:21:01,550 --> 01:21:04,970 In addition to that, there's another base case here. 1690 01:21:04,970 --> 01:21:07,885 This is I've got no eggs left, but some floors to check, 1691 01:21:07,885 --> 01:21:15,000 is the second one, i minus 1e. 1692 01:21:15,000 --> 01:21:18,330 So in this case, I've got e eggs left, and I'm done, right? 1693 01:21:18,330 --> 01:21:21,588 I've narrowed it down to the bounds. 1694 01:21:21,588 --> 01:21:23,880 Incidentally, the way I wrote it in terms of inclusive, 1695 01:21:23,880 --> 01:21:27,230 versus exclusive, might be a little fishy. 1696 01:21:27,230 --> 01:21:29,060 Over here, you guys shouldn't be off by 1, 1697 01:21:29,060 --> 01:21:31,280 like your instructor often is. 1698 01:21:31,280 --> 01:21:33,578 But in any event, here, you're 0, right? 1699 01:21:33,578 --> 01:21:35,120 There's no more floors left to check. 1700 01:21:35,120 --> 01:21:37,500 You've narrowed it down to a range of 1. 1701 01:21:37,500 --> 01:21:39,060 Again, something that I'm out of time 1702 01:21:39,060 --> 01:21:40,560 so I'm not going to check carefully, 1703 01:21:40,560 --> 01:21:44,270 is if my bounds are inclusive, should that be i, j minus 1-- 1704 01:21:44,270 --> 01:21:45,742 i minus 1 or just i, i? 1705 01:21:45,742 --> 01:21:47,450 But I think you guys are all smart enough 1706 01:21:47,450 --> 01:21:49,530 to work that out at home,. 1707 01:21:49,530 --> 01:21:52,640 Which would my original case be, well, now I 1708 01:21:52,640 --> 01:21:55,940 have all the floors to check, and all my eggs 1709 01:21:55,940 --> 01:21:58,430 in my metaphorical basket here. 1710 01:21:58,430 --> 01:22:04,940 So I have floors 1 to n here. 1711 01:22:04,940 --> 01:22:09,050 And the problem tells me I have k eggs when I start. 1712 01:22:09,050 --> 01:22:16,020 And then finally, I need to do my sub-problems here. 1713 01:22:16,020 --> 01:22:18,690 I think you can actually simplify the argument that's 1714 01:22:18,690 --> 01:22:20,490 written down a tiny bit. 1715 01:22:20,490 --> 01:22:22,690 And just again, look at your sub-problems. 1716 01:22:22,690 --> 01:22:25,520 They're indexed by three numbers, 1717 01:22:25,520 --> 01:22:27,480 I'm going to do a really conservative estimate. 1718 01:22:27,480 --> 01:22:29,855 I think the problem actually works out a better estimate, 1719 01:22:29,855 --> 01:22:33,030 but then asymptotically, it's the same. 1720 01:22:33,030 --> 01:22:35,360 What's our bound on the first and second index? 1721 01:22:35,360 --> 01:22:37,640 Well, they're both just the index 1722 01:22:37,640 --> 01:22:41,730 of floors, which go between 0 and n. 1723 01:22:41,730 --> 01:22:42,230 Yeah? 1724 01:22:42,230 --> 01:22:44,330 Obviously, you could do better than that, because the lower 1725 01:22:44,330 --> 01:22:46,455 floor is always less than the upper floor, which is 1726 01:22:46,455 --> 01:22:47,930 what the problem accounts for. 1727 01:22:47,930 --> 01:22:52,400 But if I'm being lazy, then, well, there's 1728 01:22:52,400 --> 01:22:57,470 n squared sub-problems to account for the two floors. 1729 01:22:57,470 --> 01:23:00,560 And the third index is your eggs, 1730 01:23:00,560 --> 01:23:03,650 which you have at most k of. 1731 01:23:03,650 --> 01:23:08,960 OK, how much work do we have per sub-problem? 1732 01:23:08,960 --> 01:23:11,030 Well, let's see here. 1733 01:23:11,030 --> 01:23:13,175 There's a for loop over f. 1734 01:23:13,175 --> 01:23:14,510 f Is over floors. 1735 01:23:14,510 --> 01:23:17,150 Again, if I'm going to be really conservative, 1736 01:23:17,150 --> 01:23:22,860 well, there's at most n floors total in my building. 1737 01:23:22,860 --> 01:23:27,200 And so that leads us to a runtime and n cubed k, 1738 01:23:27,200 --> 01:23:29,780 which is what we wanted, at the end of the day. 1739 01:23:29,780 --> 01:23:30,280 OK? 1740 01:23:33,230 --> 01:23:35,690 This should be a big O here, because I think technically, 1741 01:23:35,690 --> 01:23:39,740 this is n plus 1, to account for floor zero. 1742 01:23:39,740 --> 01:23:42,490 OK. 1743 01:23:42,490 --> 01:23:46,075 And that solves our egg-drop experiment. 1744 01:23:46,075 --> 01:23:47,200 I think this is a nice one. 1745 01:23:47,200 --> 01:23:48,700 And I think, in my mind, actually, 1746 01:23:48,700 --> 01:23:50,242 in terms of dynamic programming, this 1747 01:23:50,242 --> 01:23:52,510 is one of the harder things to get right, 1748 01:23:52,510 --> 01:23:57,315 which are these mini-max games. 1749 01:23:57,315 --> 01:23:58,690 I'd have to think about it, which 1750 01:23:58,690 --> 01:24:02,800 in my negative two minutes, I'm not going to have time to do. 1751 01:24:02,800 --> 01:24:06,962 I think in lecture, the way that we solve minimize problem 1752 01:24:06,962 --> 01:24:08,670 was we separated out the min and the max, 1753 01:24:08,670 --> 01:24:11,100 and we thought of there being two dynamic programming 1754 01:24:11,100 --> 01:24:13,110 problems that are interacting with each other. 1755 01:24:13,110 --> 01:24:15,870 You could probably write this one in that form, as well, 1756 01:24:15,870 --> 01:24:18,240 I guess, just by pulling this term out and thinking 1757 01:24:18,240 --> 01:24:21,210 of it as a different array. 1758 01:24:21,210 --> 01:24:22,800 But this form is perfectly fine, too. 1759 01:24:22,800 --> 01:24:23,550 Either one's all right. 1760 01:24:23,550 --> 01:24:25,530 But in my mind, these are the hardest things 1761 01:24:25,530 --> 01:24:27,230 to get right in dynamic programming. 1762 01:24:27,230 --> 01:24:30,840 So I would choose whichever one jives in your brain. 1763 01:24:30,840 --> 01:24:34,750 So in your thing, should we choose to leave it alone? 1764 01:24:34,750 --> 01:24:37,140 There is a fifth problem here, which, as usual, 1765 01:24:37,140 --> 01:24:40,740 I haven't managed to get to, where you're building walls 1766 01:24:40,740 --> 01:24:41,560 by placing tiles. 1767 01:24:41,560 --> 01:24:43,560 This is an interesting one, because your runtime 1768 01:24:43,560 --> 01:24:45,150 is exponential. 1769 01:24:45,150 --> 01:24:47,970 But the problem tells you that that's allowed. 1770 01:24:47,970 --> 01:24:50,130 But there's some exponential things which are OK 1771 01:24:50,130 --> 01:24:51,510 and some that are not. 1772 01:24:51,510 --> 01:24:53,610 Essentially, what you don't want is the product 1773 01:24:53,610 --> 01:24:54,840 of two giant exponentials. 1774 01:24:54,840 --> 01:24:57,000 You'd like to just get it down to one. 1775 01:24:57,000 --> 01:24:58,500 AUDIENCE: It's basically saying it's 1776 01:24:58,500 --> 01:25:01,050 going to be polynomial [INAUDIBLE] small [INAUDIBLE].. 1777 01:25:01,050 --> 01:25:01,560 JUSTIN SOLOMON: That's right. 1778 01:25:01,560 --> 01:25:04,080 Or it's polynomial in everything except for the things 1779 01:25:04,080 --> 01:25:06,205 it's exponential in. 1780 01:25:06,205 --> 01:25:09,090 And moreover, the things it's exponential in are small. 1781 01:25:09,090 --> 01:25:10,360 And the problem says that. 1782 01:25:10,360 --> 01:25:12,120 So I encourage you guys to take a look. 1783 01:25:12,120 --> 01:25:14,140 Because it really does take some time to logic through it. 1784 01:25:14,140 --> 01:25:15,557 But the setup for that problem is, 1785 01:25:15,557 --> 01:25:18,990 I think, longer than my glacially slow board-writing 1786 01:25:18,990 --> 01:25:20,910 can handle. 1787 01:25:20,910 --> 01:25:24,140 But with that, we'll call it for the day.