1.編輯距離
/*
* 最小編輯代價
* */
public int minCost(String str1,String str2,int ic,int dc,int rc){
if(str1==null||str2==null) return 0;
char s1[]=str1.toCharArray();
char s2[]=str2.toCharArray();
int n1=s1.length;
int n2=s2.length;
int dp[][]=new int[n1+1][n2+1];//dp[i][j]表示s1中前i-1個字符s1[0...i-1]轉化爲s2中前j-1個字符s2[0...j-1]需要的最小編輯代價.
// dp[0][0]代表''->'',所以dp[0][0]=0
for(int i=1;i<=n1;i++){//用s1[0...i]轉化爲''的最小編輯代價
dp[i][0]=i*dc;
}
for(int j=1;j<=n2;j++){//用‘’轉化爲s2[0...j]的最小編輯代價
dp[0][j]=j*ic;
}
for(int i=1;i<=n1;i++){
for(int j=1;j<=n2;j++){
if(s1[i-1]==s2[j-1]){//s1[i-1]==s[j-1]時,s1[0...i-1]轉化爲s2[0...j-1]的代價就是 s1[0...i-2]轉化爲s2[0...j-2],即dp[i-1][j-1]
dp[i][j]=dp[i-1][j-1];
}else{//s1[i]!=s[j]時,s1[0...i-1]轉化爲s2[0...j-1]的代價就是 s1[0...i-2]轉化爲s2[0...j-2]的代價加上一個替換操作(s1[i-1]->s2[i-1])的代價,即dp[i-1][j-1]+rc.
dp[i][j]=dp[i-1][j-1]+rc;
}
dp[i][j]=Math.min(dp[i][j],dp[i-1][j]+rc);//比較此時的代價取小:用s1[0...i-2]編輯成s2[0...j-1]的代價,加上一個刪除s1[i-1]的操作
dp[i][j]=Math.min(dp[i][j],dp[i][j-1]+ic);//比較此時的代價取小:用s1[0...i-1]編輯成s2[0...j-2]的代價,加上一個添入s2[i-1]的操作
}
}
return dp[n1][n2];
}
/*
* 題目:編輯距離
* 題目描述:
* 給定兩個單詞 word1 和 word2,計算出將 word1 轉換成 word2 所使用的最少操作數 。
* 你可以對一個單詞進行如下三種操作:
* 插入一個字符;刪除一個字符;替換一個字符
* */
public int minDistance2(String word1, String word2) {
return minCost(word1,word2,1,1,1);
}
2.複製粘貼字符
/*
* 題目描述:複製粘貼字符
* 題目描述:最開始只有一個字符 A,問最少需要多少次操作能夠得到 n 個字符 A,每次操作可以複製當前所有的字符,或者粘貼。
*
* */
public int minSteps(int n) {
int dp[]=new int[n+1];//dp[i]表示得到i個字符需要的最少步數
dp[1]=0;
/*
* 得到i個字符的方式只能是如下兩種方案之一:(比較所有方案找到操作次數最少的那個)
* 1.複製1個字符後,粘貼i-1次
* 2.找到i的因數j,複製1次(i/j)個字符,粘貼j-1次。(第二種方式計算dp[i]的前提是已知dp[i/j],所以可以用動態規劃的方式,依次計算dp[i]並保存)
* */
for(int i=2;i<=n;i++){
dp[i]=i;
for(int j=2;j<=Math.sqrt(n);j++){
if(i%j==0) dp[i]=Math.min(dp[i],dp[i/j]+j);
}
}
return dp[n];
}