class Solution {
public int numDistinct(String s, String t) {
int[][] dp=new int[s.length()+1][t.length()+1];
for(int i=0;i<dp.length;i++)
dp[i][0]=1;
for(int j=1;j<=t.length();j++)
{
for(int i=1;i<=s.length();i++)
{
if(s.charAt(i-1)==t.charAt(j-1))
dp[i][j]+=dp[i-1][j-1]+dp[i-1][j];
else
dp[i][j]+=dp[i-1][j];
}
}
return dp[s.length()][t.length()];
}
}
/*
b a g
0 1 2 3
0 1 0 0 0
b 1 1 1 0 0
a 2 1 1 1 0
b 3 1 2 1 0
g 4 1 2 1 1
b 5 1 3 1 1
a 6 1 3 4 1
g 7 1 3 4 5
dp[i][j] means the number of subsequences of s(0, i) equals to t(0, j). If s.charAt(i) == t.charAt(j)
*/
132. Palindrome Partitioning II
class Solution {
public int minCut(String s) {
int n=s.length();
boolean[][] dp=new boolean[n][n];
int[] minCut=new int[n]; //minCut[i]:the minimum cut of substring s[0....i]
for(int tail=0;tail<n;tail++)
{
int curMinCut=tail;
for(int head=0;head<=tail;head++)
{
if(s.charAt(head)==s.charAt(tail) && (head+1>tail-1 || dp[head+1][tail-1]))
{
dp[head][tail]=true;
if(head==0)
curMinCut=0;
else
curMinCut=Math.min(curMinCut,minCut[head-1]+1);
}
}
minCut[tail]=curMinCut;
}
return minCut[n-1];
}
}
174. Dungeon Game
解法一:自底向上:
class Solution {
public int calculateMinimumHP(int[][] dungeon) {
int M=dungeon.length;
int N=dungeon[0].length;
int[][] dp=new int[M][N];
dp[M-1][N-1]=Math.max(1,1-dungeon[M-1][N-1]);
for(int i=M-2;i>=0;i--)
{
dp[i][N-1]=Math.max(1,dp[i+1][N-1]-dungeon[i][N-1]);
}
for(int i=N-2;i>=0;i--)
{
dp[M-1][i]=Math.max(1,dp[M-1][i+1]-dungeon[M-1][i]);
}
for(int i=M-2;i>=0;i--)
{
for(int j=N-2;j>=0;j--)
{
dp[i][j]=Math.max(Math.min(dp[i+1][j],dp[i][j+1])-dungeon[i][j],1);
}
}
return dp[0][0];
}
}
解法二:自顶向下
class Solution {
public static int[][] minHP;
public int calculateMinimumHP(int[][] dungeon) {
int M=dungeon.length;
int N=dungeon[0].length;
minHP=new int[M][N];
return currentMinHP(0,0,dungeon);
}
public int currentMinHP(int x,int y,int[][] dungeon)
{
if(x==dungeon.length || y==dungeon[0].length)
return Integer.MAX_VALUE;
if(x==dungeon.length-1 && y==dungeon[0].length-1)
return Math.max(1,1-dungeon[x][y]);
if(minHP[x][y]!=0)
return minHP[x][y];
int rightMove=currentMinHP(x+1,y,dungeon);
int downMove=currentMinHP(x,y+1,dungeon);
minHP[x][y]=Math.max(1,Math.min(rightMove,downMove)-dungeon[x][y]);
return minHP[x][y];
}
}