一、ACWing:901. 滑雪
(1)题目描述
给定一个 RR 行 CC 列的矩阵,表示一个矩形网格滑雪场。
矩阵中第 ii 行第 jj 列的点表示滑雪场的第 ii 行第 jj 列区域的高度。
一个人从滑雪场中的某个区域内出发,每次可以向上下左右任意一个方向滑动一个单位距离。
当然,一个人能够滑动到某相邻区域的前提是该区域的高度低于自己目前所在区域的高度。
下面给出一个矩阵作为例子:
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
在给定矩阵中,一条可行的滑行轨迹为 24−17−2−124−17−2−1。
在给定矩阵中,最长的滑行轨迹为 25−24−23−…−3−2−125−24−23−…−3−2−1,沿途共经过 2525 个区域。
现在给定你一个二维矩阵表示滑雪场各区域的高度,请你找出在该滑雪场中能够完成的最长滑雪轨迹,并输出其长度(可经过最大区域数)。
输入格式
第一行包含两个整数 RR 和 CC。
接下来 RR 行,每行包含 CC 个整数,表示完整的二维矩阵。
输出格式
输出一个整数,表示可完成的最长滑雪长度。
数据范围
1≤R,C≤3001≤R,C≤300,
0≤矩阵中整数≤100000≤矩阵中整数≤10000
输入样例:
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
输出样例:
25
(2)代码实现
import java.util.*;
public class Main
{
static Scanner in = new Scanner(System.in);
static int N = 310;
static int h[][] = new int[N][N], f[][] = new int[N][N];
static int n, m;
static int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
public static int dp(int x,int y)
{
if (f[x][y] != -1) return f[x][y];
f[x][y] = 1;
for (int i = 0; i < 4; i++)
{
int a = x + dx[i], b = y + dy[i];
if (a >= 0 && a < n && b >= 0 && b < m && h[a][b] < h[x][y])
f[x][y] = Math.max(f[x][y], dp(a, b) + 1);
}
return f[x][y];
}
public static void main(String args[])
{
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
f[i][j] = -1;
n = in.nextInt(); m = in.nextInt();
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
h[i][j] = in.nextInt();
int ans = -1;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
ans = Math.max(ans, dp(i, j));
System.out.println(ans);
}
}
二、ACWing:285. 没有上司的舞会
(1)问题描述
Ural 大学有 NN 名职员,编号为 1∼N1∼N。
他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。
每个职员有一个快乐指数,用整数 HiHi 给出,其中 1≤i≤N1≤i≤N。
现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。
输入格式
第一行一个整数 NN。
接下来 NN 行,第 ii 行表示 ii 号职员的快乐指数 HiHi。
接下来 N−1N−1 行,每行输入一对整数 L,KL,K,表示 KK 是 LL 的直接上司。
输出格式
输出最大的快乐指数。
数据范围
1≤N≤60001≤N≤6000,
−128≤Hi≤127−128≤Hi≤127
输入样例:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
输出样例:
5
(2)代码实现
import java.util.*;
public class Main
{
static Scanner in = new Scanner(System.in);
static int N = 6010;
static int hp[] = new int[N], f[][] = new int[N][2];
static int h[] = new int[N], e[] = new int[N], ne[] = new int[N], idx;
static boolean hf[] = new boolean[N];
static void add(int a, int b)
{
e[idx] = b; ne[idx] = h[a]; h[a] = idx++;
}
static void dfs(int u)
{
f[u][1] = hp[u];
for (int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];//j是子节点
dfs(j);
f[u][0] += Math.max(f[j][0], f[j][1]);
f[u][1] += f[j][0];
}
}
public static void main(String args[])
{
for (int i = 0; i < N; i++) h[i] = -1;
int n = in.nextInt();
for (int i = 1; i <= n; i++) hp[i] = in.nextInt();
for (int i = 0; i < n - 1; i++)
{
int a = in.nextInt(), b = in.nextInt();
hf[a] = true;
add(b, a);
}
int root = 1;
while (hf[root]) root++;
dfs(root);
System.out.println(Math.max(f[root][0], f[root][1]));
}
}
三、蓝桥杯试题 算法提高 吃鱼丸
(1)问题描述
问题描述
UOI要吃鱼丸。很多很多的鱼丸……你可以近似认为是无穷多。他可以一口吃1个,也可一口吃3个,可是他不想变2,所以从来不一口吃2个。UOI想知道,吃N个鱼丸有多少种方法。
输入格式
第一行一个整数N表示鱼丸的个数。
输出格式
一个整数表示吃鱼丸的方法数。
样例输入
3
样例输出
2
数据规模和约定
1<=N<=70
(2)代码实现
import java.util.*;
public class Main{
static Scanner in=new Scanner(System.in);
public static void main(String[] args){
int N=in.nextInt();
long[] arr=new long[75];
arr[1]=1;
arr[2]=1;
arr[3]=2;
for(int i=4;i<=70;i++){
arr[i]=arr[i-1]+arr[i-3];
}
System.out.println(arr[N]);
}
}