312戳气球
solve(i,j)= (mid=i+1)max(j−1)val[i]×val[mid]×val[j]+solve(i,mid)+solve(mid,j),
(i<j−1)
class Solution {
public int maxCoins(int[] nums) {
int num = nums.length;
int [][] dp = new int[num+2][num+2];
int []val = new int[num+2];
val[0] = 1;
val[num+1] = 1;
for(int i=1;i<=num;i++)
{
val[i] = nums[i-1];
}
for(int i = num-1 ;i>=0;--i)
{
for(int j=i+2;j<num+2;j++)
{
for(int k=i+1;k<j;k++)
{
int sum = val[i]*val[j]*val[k];
sum+=dp[i][k]+dp[k][j];
dp[i][j] = Math.max(dp[i][j],sum);
}
}
}
return dp[0][num+1];
}
}
1547切木棍
f[i][j]= k∈[i,j]min{f[i][k−1]+f[k+1][j]}+(cuts[j+1]−cuts[i−1])
class Solution {
public int minCost(int n, int[] cuts) {
int m=cuts.length;
Arrays.sort(cuts);
int[] newcuts = new int[m+2];
newcuts[0] = 0;
for(int i =0;i<m;i++)
{
newcuts[i+1] = cuts[i];
}
newcuts[m+1] = n;
int [][]f = new int[m+2][m+2];
for(int i = m;i>=1;i--)
{
for(int j = i;j<=m;j++)
{
f[i][j] = (i==j?0:Integer.MAX_VALUE);
for(int k=i;k<=j;k++)
{
f[i][j] = Math.min(f[i][j],f[i][k-1]+f[k+1][j]);
}
f[i][j]+=newcuts[j+1]-newcuts[i-1];
}
}
return f[1][m];
}
}
拆陆地,一道有意思的脑筋急转弯
class Solution {
int[] dx = new int[]{0,1,0,-1};
int[] dy = new int[]{1,0,-1,0};
public int minDays(int[][] grid) {
int m = grid[0].length;
int n = grid.length;
if(count(grid,n,m)!=1)
{
System.out.println(0);
return 0;
}
for(int i =0;i<n;++i)
{
for(int j =0;j<m;++j)
{
if(grid[i][j]==1)
{
grid[i][j] =0;
if(count(grid,n,m)!=1)
{
return 1;
}
grid[i][j]=1;
}
}
}
return 2;
}
public int count(int grid[][],int n,int m)
{
int cnt =0;
for(int i=0;i<n;++i)
{
for(int j=0;j<m;++j)
{
if(grid[i][j]==1)
{
cnt++;
System.out.println(cnt);
dfs(i,j,grid,n,m);
}
}
}
for(int i=0;i<n;++i)
{
for(int j=0;j<m;++j)
{
if(grid[i][j]==2)
{
grid[i][j]=1;
}
}
}
return cnt;
}
public void dfs(int x,int y,int grid[][],int n,int m)
{
grid[x][y]=2;
for(int i=0;i<4;i++)
{
int tx = dx[i]+x;
int ty = dy[i] + y;
if(tx>=n||ty>=m||tx<0||ty<0||grid[tx][ty]!=1)
continue;
dfs(tx,ty,grid,n,m);
}
}
}
DNA 是由 ACGT 四种核苷酸组成,例如 AAAGTCTGAC,假定自然环境下 DNA 发生异变的情况有:
基因缺失一个核苷酸
基因新增一个核苷酸
基因替换一个核苷酸
且发生概率相同。
古生物学家 Sam 得到了若干条相似 DNA 序列,Sam 认为一个 DNA 序列向另外一个 DNA 序列转变所需的最小异变情况数可以代表其物种血缘相近程度,异变情况数越少,血缘越相近,请帮助 Sam 实现获取两条 DNA 序列的最小异变情况数的算法。
格式:
输入:
- 每个样例只有一行,两个 DNA 序列字符串以英文逗号“,”分割
输出: - 输出转变所需的最少情况数,类型是数字
示例:
输入:ACT,AGCT
输出:1
提示:
每个 DNA 序列不超过 100 个字符
import java.util.*;
import java.lang.*;
public class Solution{
private static int minNum(String str1,String str2)
{
int len1 = str1.length();
int len2 = str2.length();
if(len1==0||len2==0)
return len1==0?len2:len1;
int [][]dp = new int[len1+1][len2+1];
dp[0][0] = 0;
for(int i=1;i<=len1;i++)
{
dp[i][0] = i;
}
for(int j=1;j<len2;j++)
{
dp[0][j]=j;
}
for(int i=1;i<=len1;i++)
{
for(int j=1;j<=len2;j++)
{
if(str1.charAt(i-1)==str2.charAt(j-1))
{
dp[i][j] = Math.min(dp[i-1][j-1],Math.min(dp[i-1][j],dp[i][j-1])+1);
}
else
{
dp[i][j] = Math.min(dp[i-1][j-1]+1,Math.min(dp[i-1][j],dp[i][j-1])+1);
}
}
}
return dp[len1][len2];
}
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String input = "";
if(scan.hasNext())
{
input = scan.nextLine();
}
scan.close();
String[] array = input.split(",");
System.out.println(minNum(array[0],array[1]));
}
}
最大矩形的做法,使用动态规划,要使用三次,之前刷过的poj上面的解法使用的是状态压缩,找到从前的代码我再贴出来
class Solution {
public int maximalRectangle(char[][] matrix) {
int row,col;
if((matrix==null||matrix.length==0)||(matrix.length==1&&matrix[0].length==0))
return 0;
row = matrix.length;
col = matrix[0].length;
int []left = new int[col];
int []right = new int[col];
int []height = new int[col];
Arrays.fill(left,0);
Arrays.fill(right,col);
Arrays.fill(height,0);
int maxarea=0;
for(int i=0;i<row;++i)
{
int curleft = 0;
int curright = col;
for(int j=0;j<col;++j)
{
if(matrix[i][j]=='1')
{
height[j]=height[j]+1;
//System.out.println(height[j]);
}
else
height[j] = 0;
}
for(int j =0;j<col;++j)
{
if(matrix[i][j]=='1')
{
left[j] = Math.max(curleft,left[j]);
}
else{
curleft=j+1;
left[j]=0;
}
}
for(int j =col-1;j>=0;--j)
{
if(matrix[i][j]=='1')
{
right[j] = Math.min(right[j],curright);
}
else
{
right[j] = col;
curright=j;
}
}
for(int j=0;j<col;++j)
{
maxarea = Math.max(maxarea,height[j]*(right[j]-left[j]));
// System.out.println(height[j]);
}
}
return maxarea;
}
}
参考文章
最大矩形(动态规划,最大柱状图)
上面两道题比较类似,可以清楚的做对比。
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。
注意:
num 的长度小于 10002 且 ≥ k。
num 不会包含任何前导零。
示例 1 :
输入: num = “1432219”, k = 3
输出: “1219”
解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。
示例 2 :
输入: num = “10200”, k = 1
输出: “200”
解释: 移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。
示例 3 :
输入: num = “10”, k = 2
输出: “0”
解释: 从原数字移除所有的数字,剩余为空就是0。
class Solution {
public String removeKdigits(String num, int k) {
int m = num.length();
if(m == k)
return "0";
StringBuilder s = new StringBuilder(num);
for(int i =0;i<k;i++)
{
int sat = 0;
for(int j=1;j<s.length()&&s.charAt(j)>=s.charAt(j-1);j++)
{
sat = j;
}
s.delete(sat,sat+1);
while(s.length()>1&&s.charAt(0)=='0')
{
s.delete(0,1);
}
}
return s.toString();
}
}
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \
3 2 1 1 3 2
/ / \
2 1 2 3
class Solution {
public int numTrees(int n) {
int [] dp = new int[n+1];
dp[0] =1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
dp[i]+=dp[j-1]*dp[i-j];
}
}
return dp[n];
}
}```