LeetCode——DP

字符串问题

回文子串是连续的,而子序列则不一定连续。
5.最长回文子串
647.回文子串
516.最长回文子序列
1143.最长公共子序列
最长公共子串

public int getLCS(String s, String t) {
        if (s == null || t == null) {
            return 0;
        }
        int result = 0;
        int sLength = s.length();
        int tLength = t.length();
        int[][] dp = new int[sLength + 1][tLength + 1];
        for (int i = 1; i <= sLength; i++) {
            for (int k = 1; k <= tLength; k++) {
                if (s.charAt(i - 1) == t.charAt(k - 1)) {
                    dp[i][k] = dp[i - 1][k - 1] + 1;
                    result = Math.max(dp[i][k], result);
                }
            }
        }
        return result;
    }

股票问题

121.买卖股票的最佳时机
122.买卖股票的最佳时机II
123.买卖股票的最佳时机III
188.买卖股票的最佳时机IV
309.最佳买卖股票时机含冷冻期
714.买卖股票股票最佳时机含手续费

最长子序列问题

300和646的不同之处在于646会先排序,因此可以返回dp[len-1],而300是无序的,因此需要返回以全局的Max。
300.最长上升子序列
646.最长数对链
673.最长递增子序列的个数
712.两个字符串的最小ASCII删除和
413.等差数列划分

0-1背包问题

416.分割等和子集
1049.最后一块石头的重量II
474.一和零
有 N 件物品和一个容量为 V 的背包。第 i 件物品的体积是 C[i],价值是 W[i]。求解将哪些物品装入背包可使价值总和最大,求出最大总价值。

	public static int zeroOnePack(int V, int[] C, int[] W){
		if(V <= 0 || C.length != W.length)
			return 0;
		int n = C.length;
		int[][] dp = new int[n + 1][V + 1];
		for(int i = 0; i <= n; i++){
			for(int j = 0; j <= V; j++){
				if(j < C[i - 1])// 背包放不下第 i 个物品
					dp[i][j] = dp[i - 1][j];
				else// 背包能放下第 i 个物品,选择价值最大的方案
					dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - C[i - 1]] + W[i - 1]);
			}
		}
		return dp[n][V];
	}
	空间优化:
	public static int zeroOnePackOpt(int V, int[] C, int[] W){
		if(V <= 0 || C.length != W.length)
			return 0;
		int n = C.length;
		int[] dp = new int[V + 1];
		dp[0] = 0;// 背包为空时,价值为 0
		for(int i = 0; i < n; i++){
			for(int j = V; j >= C[i]; j--){
				dp[j] = Math.max(dp[j], dp[j - C[i]] + W[i]);
			}
		}
		return dp[V];
	}

两个人抓数问题

486.预测赢家
464.我能赢吗

视频拼接问题

1024.视频拼接

零钱兑换问题

322.零钱兑换
983.最低票价
718.最长重复子数组

马跳棋盘问题

688.“马”在棋盘上的概率
576.出界的路径数
935.骑士拨号器

连续子序列/打家劫舍问题

152.乘积最大子序列
53.最大子序和
713.成绩小于K的子数组
198.打家劫舍
213.打家劫舍II
337.打家劫舍III

二叉搜索树与Dp

96.不同的二叉搜索树
95.不同的二叉搜索树II

路径问题

64.最小路径和
62.不同路径
63.不同路径II

其他

467.环绕字符串中唯一的子字符串
91.解码方法
873.最长的斐波那锲子序列的长度
898.子数组按位或操作
221.最大正方形
801.使序列递增的最小交换
1027.最长等差数列
139.单词拆分
837.新21点
877.石子游戏
368.最大整除子集
813.最大平均值和的分组
120.三角形最小路径和

有 N 堆金币排成一排,第 i 堆中有 C[i] 块金币。每次合并都会将相邻的两堆金币合并为一堆,成本为这两堆金币块数之和。经过N-1次合并,最终将所有金币合并为一堆。请找出将金币合并为一堆的最低成本。其中,1 <= N <= 30,1 <= C[i] <= 100

//dp[i][j]:i-j的最小和
import java.util.*;
class Test{
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] coin = new int[n+1];
        int[] preSum = new int[n+1];
        for(int i=1;i<=n;i++) {
            coin[i] = in.nextInt();
            if(i==1) preSum[i]=coin[i];
            else preSum[i]=preSum[i-1]+coin[i];
        }
        in.close();
        int[][] dp=new int[n+1][n+1];//i-j的最低成本
        for(int len=2;len<=n;len++){
            for(int i=1;i<=n-len+1;i++){
                int j=i+len-1;
                dp[i][j]=Integer.MAX_VALUE;
                int sum=preSum[j]-preSum[i-1];
                for(int k=i;k<j;k++){
                    dp[i][j]=Math.min(dp[i][j],dp[i][k]+dp[k+1][j]+sum);
                }
            }
        }
        System.out.println(dp[1][n]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值