How to approach DP problems
Kadane's Algorithm
v[i] = the (local) maximum subarray that ends at a[i]
(that is, either v[i-1]+a[i] or just itself a[i])
import sys
n = int(sys.stdin.readline())
a = list(map(int, sys.stdin.readline().split()))
v = [0]*n
v[0] = a[0]
largest = v[0]
for i in range(1, n):
v[i] = v[i-1]+a[i]
if v[i]<a[i]:
v[i] = a[i]
if v[i]>largest:
largest = v[i]
print(largest)
lis[i] = the length of the LIS that ends at xi
import sys
n = int(sys.stdin.readline())
a = list(map(int, sys.stdin.readline().split()))
lis = [1]*n
for i in range(1, n):
longest = -1
for j in range(i):
if a[i]>a[j]:
longest = max(longest, lis[j])
if longest!=-1:
lis[i] += longest
print(max(lis))
Alternative Solution using LCS
lcs[i][j] = the length of the LCS of X[1..i] and Y[1..j]
import sys
x = sys.stdin.readline().strip()
y = sys.stdin.readline().strip()
m = len(x)
n = len(y)
lcs = [[None]*(n+1) for _ in range(m+1)]
for i in range(m+1):
for j in range(n+1):
if i==0 or j==0:
lcs[i][j] = 0
elif x[i-1]==y[j-1]:
lcs[i][j] = lcs[i-1][j-1]+1
else:
lcs[i][j] = max(lcs[i-1][j], lcs[i][j-1])
print(lcs[m][n])
dp[i][j] = the largest value possible using the first i items with knapsack capacity j
import sys
n, w = map(int, sys.stdin.readline().split())
wt = [0]
v = [0]
for _ in range(n):
a, b = map(int, sys.stdin.readline().split())
wt.append(a)
v.append(b)
dp = [[0]*(w+1) for _ in range(n+1)]
for i in range(1, n+1):
for j in range(1, w+1):
if wt[i]<=j:
dp[i][j] = max(v[i]+dp[i-1][j-wt[i]], dp[i-1][j])
else:
dp[i][j] = dp[i-1][j]
print(dp[n][w])