1.跳台阶
问题描述:
小蓝要上楼梯,楼梯总共n阶,小蓝每一步可以走a,b,c级台阶
请问小蓝总共有多少种方法刚好走到楼梯顶端
public class FrogJump {
public static int countWays(int n, int a, int b, int c) {
int[] dp = new int[n+1];
dp[0] = 1;
for (int i = 1; i <= n; i++) {
if (i >= a) {
dp[i] += dp[i - a];
}
if (i >= b) {
dp[i] += dp[i - b];
}
if (i >= c) {
dp[i] += dp[i - c];
}
}
return dp[n];
}
public static void main(String[] args) {
int n = 10; // 台阶数
int a = 1; // 青蛙可以跳的阶数a
int b = 2; // 青蛙可以跳的阶数b
int c = 3; // 青蛙可以跳的阶数c
int result = countWays(n, a, b, c);
System.out.println("青蛙跳完所有台阶的跳法数量为: " + result);
}
}
数字三角形
题目描述
观察下面的数字金字塔。
写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
在上面的样例中,从 7→3→8→7→57→3→8→7→5 的路径产生了最大权值。
输入格式
第一个行一个正整数 �r ,表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
输出格式
单独的一行,包含那个可能得到的最大的和。
输入输出样例
输入 #1复制
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
输出 #1复制
30
说明/提示
【数据范围】
对于 100%100% 的数据,1≤�≤10001≤r≤1000,所有输入在 [0,100][0,100] 范围内。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
//创建数组对三角形进行存储
int[][] a = new int[1001][1001];
//输入三角形
for (int i=1;i<=n;i++){
for (int j=1;j<=i;j++){
a[i][j] = scanner.nextInt();
}
}
//反向递推
for (int i=n-1;i>=1;i--){ //从最后一层开始
for (int j=1;j<=i;j++){
a[i][j]+=Math.max(a[i+1][j],a[i+1][j+1]);
}}
System.out.println(a[1][1]);
}
}
反向递推,选择比较大的为基底
延伸:将左右移动的差值限定比如往左和往右移的次数差值不能超过1,学完可以去试试
挖地雷
题目描述
在一个地图上有 � (�≤20)N (N≤20) 个地窖,每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
输入格式
有若干行。
第 11 行只有一个数字,表示地窖的个数 �N。
第 22 行有 �N 个数,分别表示每个地窖中的地雷个数。
第 33 行至第 �+1N+1 行表示地窖之间的连接情况:
第 33 行有 �−1n−1 个数(00 或 11),表示第一个地窖至第 22 个、第 33 个 …… 第 �n 个地窖有否路径连接。如第 33 行为 11000⋯011000⋯0,则表示第 11 个地窖至第 22 个地窖有路径,至第 33 个地窖有路径,至第 44 个地窖、第 55 个 …… 第 �n 个地窖没有路径。
第 44 行有 �−2n−2 个数,表示第二个地窖至第 33 个、第 44 个 …… 第 �n 个地窖有否路径连接。
……
第 �+1n+1 行有 11 个数,表示第 �−1n−1 个地窖至第 �n 个地窖有否路径连接。(为 00 表示没有路径,为 11 表示有路径)。
输出格式
第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。
第二行只有一个数,表示能挖到的最多地雷数。
输入输出样例
输入 #1复制
5 10 8 4 7 6 1 1 1 0 0 0 0 1 1 1
输出 #1复制
1 3 4 5 27
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//表示地窖的个数 n
int n = sc.nextInt();
//表示每个地窖中的地窖中的地雷个数
int[] nums = new int[n + 1],
//表示到该地窖路径下的最大地雷数
dp = new int[n + 1];
for (int i = 1; i <= n; i++) {
nums[i] = dp[i] = sc.nextInt();
}
//表示地窖间是否有连接
int[][] arr = new int[n + 1][n + 1];
for (int i = 1; i < n; i++) {
for (int j = i + 1; j <= n; j++) {
arr[i][j] = sc.nextInt();
}
}
//用来记录路径的数组
int[] path = new int[n + 1];
for (int i = n - 1; i >= 1; i--) {
int maxNum = 0, next = 0;
for (int j = i + 1; j <= n; j++) {
//判断i,j是否存在路径
if (arr[i][j] == 1 && dp[j] > maxNum) {
maxNum = dp[j];
next = j;
}
dp[i] = maxNum + nums[i];
//将该点存入最大路径中
path[i] = next;
}
}
int index = 1, ans = dp[1];
for (int i = 1; i <= n; i++) {
if (dp[i] > dp[index]) {
ans = dp[i];
index = i;
}
}
//遍历路径
while (index != 0) {
System.out.print(index + " ");
index = path[index];
}
System.out.println();
System.out.println(ans);
}
}
过河卒
题目描述
棋盘上 �A 点有一个过河卒,需要走到目标 �B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 �C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,�A 点 (0,0)(0,0)、�B 点 (�,�)(n,m),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 �A 点能够到达 �B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个正整数,分别表示 �B 点坐标和马的坐标。
输出格式
一个整数,表示所有的路径条数。
输入输出样例
输入 #1复制
6 6 3 3
输出 #1复制
6
说明/提示
对于 100%100% 的数据,1≤�,�≤201≤n,m≤20,0≤0≤ 马的坐标 ≤20≤20。
【题目来源】
NOIP 2002 普及组第四题
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//因为数组默认值为0,将坐标整体全部+1,这样边界的就不用去手动复制了
int n = sc.nextInt()+1, m = sc.nextInt()+1;//B点坐标
int a = sc.nextInt()+1, b = sc.nextInt()+1;//C点坐标
int[] x = {0, -2, -1, 1, 2, 2, 1, -1, -2};
int[] y = {0, 1, 2, 2, 1, -1, -2, -2, -1};
//判断是否能够走
boolean[][] road = new boolean[21][21];
//记录到达该点的路径数
int [][] dp = new int [21][21];
dp[1][1] = 1;
//记录不能走的
for (int i = 0; i < x.length; i++) {
road[a + x[i]][b + y[i]] = true;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (i == 1 && j == 1)
continue;
if (!road[i][j]) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
System.out.println(dp[n][m]);
}
}