欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第一章动态规划(一)

程序员文章站 2022-07-13 11:30:19
...

1. 数字三角形模型

例题:摘花生
原题链接

总时间限制:
1000ms
内存限制:
65536kB

描述
Hello Kitty 想摘点花生送给她喜欢的米老鼠。她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过一株花生苗就能摘走该它上面所有的花生。Hello Kitty只能向东或向南走,不能向西或向北走。问Hello Kitty 最多能够摘到多少颗花生。
第一章动态规划(一)
输入
第一行是一个整数T,代表一共有多少组数据。1<=T <= 100
接下来是T组数据。

每组数据的第一行是两个整数,分别代表花生苗的行数R和列数 C ( 1<= R,C <=100)
每组数据的接下来R行数据,从北向南依次描述每行花生苗的情况。每行数据有 C 个整数,按从西向东的顺序描述了该行每株花生苗上的花生数目 M ( 0<= M <= 1000)。
输出
对每组输入数据,输出一行,内容为Hello Kitty能摘到得最多的花生颗数。
样例输入
2
2 2
1 1
3 4
2 3
2 3 4
1 6 5
样例输出
8
16
————————————————————————————————————————————————————
第一章动态规划(一)
状态计算其实就是集合划分,集合划分的原则:不重不漏

关于边界问题:一般有 f[i - 1], f[j - 1] 这样的,我们采用下标从 1 开始
关于初始化问题:从实际问题出发进行初始化

import java.util.Scanner;

public class Main{
	static int n;
	static int t;
	static int m;
	static int[][] a;
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		t = sc.nextInt();
		while(t-- > 0) {
			n = sc.nextInt();
			m = sc.nextInt();
			a = new int[n + 1][m + 1];
			for(int i = 1;i <= n;i++) {
				for(int j = 1;j <= m;j++) {
					a[i][j] = sc.nextInt();
				}
			}
			int[][] dp = new int[n + 1][m + 1];
			for(int i = 1;i <= n;i++) dp[i][1] = dp[i - 1][1] + a[i][1];
			for(int j = 1;j <= m;j++) dp[1][j] = dp[1][j - 1] + a[1][j];
			for(int i = 2;i <= n;i++) {
				for(int j = 2;j <= m;j++) {
					dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + a[i][j];
				}
			}
			System.out.println(dp[n][m]);
		}
		sc.close();
	}
}

例题:最低通行费
原题链接

总时间限制:
1000ms
内存限制:
65536kB

描述
一个商人穿过一个 N*N 的正方形的网格,去参加一个非常重要的商务活动。他要从网格的左上角进,右下角出。每穿越中间1个小方格,都要花费1个单位时间。商人必须在(2N-1)个单位时间穿越出去。而在经过中间的每个小方格时,都需要缴纳一定的费用。

这个商人期望在规定时间内用最少费用穿越出去。请问至少需要多少费用?

注意:不能对角穿越各个小方格(即,只能向上下左右四个方向移动且不能离开网格)。
输入
第一行是一个整数,表示正方形的宽度N (1 <= N < 100);
后面 N 行,每行 N 个不大于 100 的整数,为网格上每个小方格的费用。
输出
至少需要的费用。
样例输入
5
1 4 6 8 10
2 5 7 15 17
6 8 9 18 20
10 11 12 19 21
20 23 25 29 33
样例输出
109
提示
样例中,最小值为109=1+2+5+7+9+12+19+21+33。
————————————————————————————————————————————————

相关标签: 算法提高课