## Hints for SRM 586, D2, 1000-Pointer (StringWeightDiv2)

### James S. Plank

Fri Oct 18 14:45:24 EDT 2013
Problem Statement.
This is a hard problem to think about, so let me make it easier to think about. Instead of solving it for strings that have any of the 26 characters, let's solve it for strings that just use 'a' 'b' and 'c', and then extrapolate to 26 characters.

It should be clear that when L is 1, 2 or 3, then you can easily come up with strings that have weights of zero. These are strings where no character appears twice. How many of those are there?

• 3 for L=1: a, b, and c
• 3*2 for L=2: ab, ac, ba, bc, ca, cb
• 3*2*1 for L=3: abc, acb, bac, bca, cab, cba

When L=4, you have to have at least one character that appears twice. Suppose you have a character that appears twice. Its minimum weight will be when the two appearances are next to each other. So, can we enumerate all sequences which have two characters next to each other? How about we take the 6 cases for L=3, and for each letter, we double it. So:

• abc becomes aabc, abbc, abcc.
• acb becomes aacb, accb, acbb.
• Etc.
That gives us 6*3 = 18 cases for L=4. Let's move onto L=5. We can't have any strings with weight = 1 (think about that), but we can for weight equals two. We can have two letters that are repeated once, like aabbc, or one letter that is repeated twice, like aaabc.

My first thought on enumerating these was to take each of the strings for L=4, and for each unique letter in the string, add one copy of the letter. So:

• aabc becomes aaabc, aabbc and aabcc
• abbc becomes aabbc, abbbc and abbcc
• Etc.
If you examine those cases, there's a problem because aabbc is generated twice. Back to the drawing board.

How about this -- suppose we have a function f(l, n) that returns the number of strings of length l with n distinct letters such that the letters appear consecutively and in increasing order. So:

• f(1,1) = 1: a
• f(2,1) = 1: aa
• f(3,1) = 1: aaa
• f(4,1) = 1: aaaa
• f(5,1) = 1: aaaaa

• f(1,2) = 0: Can't do it
• f(2,2) = 1: ab
• f(3,2) = 2: aab, abb
• f(4,2) = 3: aaab, aabb, abbb
• f(5,2) = 4: aaaab, aaabb, aabbb, abbbb

• f(1,3) = 0: Can't do it
• f(2,3) = 0: Can't do it
• f(3,3) = 1: abc
• f(4,3) = 3: aabc, abbc, abcc
• f(5,3) = 6: aaabc, aabbc, abbbc, aabcc, abbcc, abccc.
Can you spot the recursion?

Look at the last one: f(5,3) equals the f(4,2) strings with a single c, plus the f(3,2) strings with two c's, plus the f(2,2) string with three c's.

Convince yourself that f(6,3) will equal f(5,2)+f(4.2)+f(3,2)+f(2,2).

For any L > 3, you can calculate the number of strings with minimum weight as f(L,3) times 3! (which is the total number of ways to have strings of length 3 with distinct characters).

Now, to extrapolate this so that the strings can contain any of 26 characters, you write f(l,n) for any l ≤ 1000 and n ≤ 26 as a classic dynamic program (with memoization, or you can spot how to remove the recursion if you want). When L > 26, multiply f(L,26) by 26! to get your answer.

I'm not going to tell you any more than this. Below are the answers (taken modulo 1,000,000,009) for all L from 1 to 50:

``` 1         26
2        650
3      15600
4     358800
5    7893600
6  165765600
7  315311973
8  990927442
9  836693803
10  223794525
11  580712373
12  710685523
13  949597241
14  344764025
15  137168264
16  508850895
17   88508905
18  796580145
19  372641106
20  608487724
21  650926317
22  254631558
23   18526223
24   55578669
25  111157338
26  111157338
27  890090770
28   16225287
29  151436012
30   97911078
31  587466468
32   35243391
33  589684077
34  807446803
35  939243459
36  787352084
37  758606804
38  672370964
39  888468962
40  617877806
41  314340804
42  555498308
43  842995815
44  180489986
45  207450492
46  466763607
47  308148847
48  431045262
49  116964018
50  488801539
```