跳柱子
【题目描述】
小易有n根柱子,第i根柱子的高度为hi。一开始小易站在第一根柱子上。小易能从第i根柱子跳到第j根柱子,当且仅当hj≤hi且1≤j−i≤k。其中k为指定的一个数字。
另外小易拥有一次释放超能力的机会。这个超能力能让小易从柱子i跳到任意满足1≤j−i≤k的柱子j而无视柱子高度的限制。
现在小易想知道,小易是否能到达第n根柱子。
【输入描述】
第一行数据组数T
对于每组数据,第一行数字n,k接下来一行n个数字表示hi。
1≤n≤1000,1≤hi≤10^9,1≤T≤10,1≤k≤n
【输出描述】
对于每组数据,输出YES或NO
【示例】
示例1:
输入:
1
5 3
6 2 4 3 8
输出:
YES
示例2:
输入:
1
5 2
1 8 2 3 4
输出:
NO
【解题代码】
方案1:没有测试过
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
while (T-- > 0) {
int n = sc.nextInt();
int k = sc.nextInt();
int[] h = new int[n];
for (int i = 0; i < n; i++) {
h[i] = sc.nextInt();
}
if (solve(h, k)) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
public static boolean solve(int[] h, int k) {
boolean superPower = true;
//找k以内最高的
//找k以后比
for (int i = 0; i < h.length; ) {
int skip= -1;
int superMax = i;
for (int j = i + 1; j <= i + k && j<h.length; j++) {
//h[j] 更小
if (h[j] <= h[i]) {
if(j == h.length-1){
return true;
}
if (skip == -1 || h[skip] <= h[j]) {
skip = j;
}
} else { //h[j]更大
if(h[superMax] <= h[j]){
superMax = j;
}
}
}
if(skip == -1 && superPower){ //没用超能力
skip = superMax; //用超能力
superPower = false;
}else if(skip == -1 && !superPower){
return false;
}
i = skip;
if(i == h.length-1){
break;
}
}
return true;
}
}
方案2:动态规划
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
while (T-- > 0) {
int n = sc.nextInt();
int k = sc.nextInt();
int[] h = new int[n];
for (int i = 0; i < n; i++) {
h[i] = sc.nextInt();
}
if (solve(h, k)) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
public static boolean solve(int[] h, int k) {
for (int i = 1; i < dp.length; i++) {
// 不用超能力到达j
for (int j = i - 1; j >= i - k && j >= 0; j--) {
if (dp[j] == 1 && h[j] >= h[i]) { //前面不用超能力到达j,不用超能力,能从j到达i
dp[i] = 1;
break;
}
}
if (dp[i] == 1) continue;
for (int j = i - 1; j >= i - k && j >= 0; j--) {
if (s > 0 && dp[j] == 1 && h[j] < h[i]) {
dp[i] = 2;
break;
}
else if (dp[j] == 2 && h[j] >= h[i]) { //用超能力达到j,再直接从j到达i
dp[i] = 2;
break;
}
}
if (dp[i] == -1) dp[i] = 0; //不能直接到达 且 不能使用超能力到达,则该点就不可到达
}
return (dp[dp.length - 1] == 1 || dp[dp.length - 1] == 2);
}
}