Implementation of Longest Common Subsequence
You could use an explicit memoizer rather than incorporating caching into your function.
This will make your function easier to understand.
You can use functools lru_cache if you are using Python3.
You should evaluate based on truth, rather than length. len(s1) == 0 is 'bad'.
You can use a turnery operator to reduce the repetition of your code.
Your else can be removed, to prevent the arrow anti-pattern.
And reduce the amount of indentation.




def memoize(fn)
    def inner(*args):
        try:
            return cache[args]
        except IndexError:
            cache[args] = fn(*args)
            return cache[args]
    return inner

# Natural abstracted algorithm.
@memoize
def lcs(s1, s2):
    if not s1 or not s2:
        return 0

    return (
        1 + lcs(s1[:-1], s2[:-1])
        if s1[-1] == s2[-1] else
        max(lcs(s1[:-1], s2), lcs(s1, s2[:-1]))
    )