另外小易拥有一次释放超能力的机会。这个超能力能让小易从柱子
现在小易想知道,小易是否能到达第
第一行数据组数对于每组数据,第一行数字,接下来一行
个数字表示
.
对于每组数据,输出YES或NO
1 5 3 6 2 4 3 8
YES
1 5 2 1 8 2 3 4
NO
t = int(input())
for _ in range(t):
n, k = list(map(int, input().split()))
li = list(map(int, input().split()))
dp = [[False, 1] for _ in range(n)]
dp[0][0] = True
for i in range(1, n):
flag = False
max1 = 0
for j in range(max(0, i - k), i):
if dp[j][0] == False:
continue
elif li[j] >= li[i]:
dp[i] = dp[j].copy()
max1 = max(max1, dp[j][1])
dp[i][1] = max1
flag = True
elif li[j] < li[i] and not flag and dp[j][1]:
dp[i] = dp[j].copy()
dp[i][1] = 0
if dp[-1][0]:
print('YES')
else:
print('NO') #include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX_N 1000+100
int T;
int N, k;
int H[MAX_N];
int dp[MAX_N][3];
int main()
{
scanf("%d", &T);
while (T--)
{
memset(dp, 0, sizeof(dp));
dp[0][1] = 1;
dp[0][0] = 1;
scanf("%d%d", &N, &k);
for (int i = 0; i < N; i++)
{
scanf("%d", &H[i]);
}
for (int i = 1; i < N; i++)
{
for (int j = 1; j <= k; j++)
{
if (i - j >= 0 && H[i] <= H[i-j]) {
dp[i][0] |= dp[i - j][0];
dp[i][1] |= dp[i - j][1];
}
dp[i][1] |= dp[i - j][0];
}
}
if (dp[N - 1][0] || dp[N - 1][1])
printf("YES\n");
else
printf("NO\n");
}
return 0;
} #include <iostream>
#include <vector>
using namespace std;
int main() {
int T = 0;
cin >> T; //数据组数
for (int i = 0; i < T; i++) {
int n = 0, k = 0;
cin >> n >> k;
vector<int> heights(n, 0);
for (int i = 0; i < n; i++) {
cin >> heights[i];
}
vector<vector<bool>> dp(n, vector<bool>(2, false));
dp[0][0] = true; //第一个位置可以到达
dp[0][1] = false; //刚开始没有用超能力
for (int j = 1; j < n; j++) {
for (int i = 0; i < j; i++) {
if (j - i > k) continue; //不满足范围条件
if (!dp[i][0]) continue; //如果i不可达
if (heights[i] >= heights[j] && dp[i][1] == false) {
//最好情况,之前没有用过超能力,现在也不用
dp[j][0] = true;
dp[j][1] = false;
break; //避免最好情况被其他情况覆盖
}
else if (heights[i] >= heights[j] && dp[i][1] == true) {
//之前用过超能力,现在不用
dp[j][0] = true;
dp[j][1] = true; //之前用过了
}
else if (heights[i] < heights[j] && dp[i][1] == false) {
//之前没有用过超能力,现在要用
dp[j][0] = true;
dp[j][1] = true;
}
else if (heights[i] < heights[j] && dp[i][1] == true) {
//之前用过超能力,现在还要用,说明无法从该i到j,默认false
//直接改false会覆盖掉其他情况
continue;
}
}
}
if (dp[n - 1][0] == true)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
} import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
int n = 0, k = 0;
for (int i = 0; i < T; i++) {
n = sc.nextInt();
k = sc.nextInt();
int[] nums = new int[n];
for (int j = 0; j < n; j++)
nums[j] = sc.nextInt();
System.out.println(solution(n, k, nums));
}
}
public static String solution(int n, int k, int[] nums) {
int big = 1;
int index = 0;
while (index < nums.length - 1) {
int tmp = index;
int max = 0, max_index = index;
for (int j = index + 1; j < index + 1 + k && j < nums.length; j++) {
if (nums[j] < nums[index]) {
max_index = (max > nums[j]) ? max_index : j;
max = Math.max(nums[j], max);
}
}
index = max_index;
if (tmp == index && big > 0) {
big--;
max = 0;
max_index = index;
for (int j = index + 1; j < index + 1 + k && j < nums.length; j++) {
max_index = (max > nums[j])? max_index : j;
max = Math.max(nums[j], max);
}
index = max_index;
}
else if (tmp == index && big <= 0)
return "NO";
}
return "YES";
}
} import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int T = in.nextInt();
List nums;
while (T-- > 0){
nums = new ArrayList();
int n = in.nextInt();
int k = in.nextInt();
for (int i = 0; i < n; i++){
nums.add(in.nextInt());
}
boolean ans = crossEnd(nums, k);
System.out.println((ans == false)?"NO":"YES");
}
}
public static boolean crossEnd(List<Integer> nums,int k){
int change = 1;
int index = 0;
while (index != nums.size() - 1){
int max = 0,maxIndex = -1;
int sMax = 0,sMaxIndex = -1;
int endIndex = Math.min(nums.size(),index + k + 1);
List<Integer> temp = nums.subList(index + 1,endIndex);
for (int i = 0; i < temp.size(); i++){
if (temp.get(i) > sMax && temp.get(i) <= nums.get(index)){
sMax = temp.get(i);
sMaxIndex = index + i + 1;
}
if (temp.get(i) > max){
max = temp.get(i);
maxIndex = index + i + 1;
}
}
if (sMaxIndex == -1 && change == 1){
index = maxIndex;
change--;
}else if (sMaxIndex == -1 && change == 0)
return false;
else {
index = sMaxIndex;
}
}
return true;
}
} function canArive2 (hs, k, n) {
let res = 'NO'
const rec = (i, canFly) => {
if (i === n - 1) {
res = 'YES'
return
}
for (let j = i + 1; j <= i + k && j <= n - 1; j++) {
if (hs[j] < hs[i] || canFly) {
let tmpCanFly = canFly
if (hs[j] > hs[i]) tmpCanFly = false
rec(j, tmpCanFly)
}
}
}
rec(0, true)
return res
} 后面想了一下,感觉应该是可以用贪心的,仔细看了一下我设的条件,“每次都找hj比hi小的,并且最远的”。这里就不对了,题目只是问能不能到达,而不是就一个最短的路径,所以干嘛用最远的呢,想了下,应该是前面k个柱子中比当前柱子低的,其中最高的那个,因为只有找相对高的,后面才可能跳得下去。改变条件后的贪心算法代码如下: function canArive1 (hs, k, n) {
let canFly = true
let i = 0
while (i < n - 1) {
// 找i+1 ~ i+k 最远的,而且低的
let nextIndex = null
let highestIndex = i + 1
for (let j = i + 1; j <= i + k; j++) {
if (hs[j] < hs[i]) nextIndex = j
if (hs[j] > hs[highestIndex]) highestIndex = j
}
if (!nextIndex) {
if (canFly) {
nextIndex = highestIndex
canFly = false
} else {
return 'NO'
}
}
i = nextIndex
}
return 'YES'
} 测试: let res = canArive([6,2,4,3,8], 3, 5) console.log(res) //YES
#include<iostream>
#include<vector>
#include<deque>
using namespace std;
int forword(vector<int>& h, int k, int start){
int n = h.size();
deque<pair<int, int>> Q;//单调递减队列
Q.push_back(make_pair(start, h[start]));
pair<int, int> cur=Q.front();
int i=start+1;
for (; i<n; ++i){
cur = Q.front();
if (i-cur.first>k)//超出范围
Q.pop_front();
if (Q.empty()) break;
if (Q.front().second < h[i])
continue;
else{
while(!Q.empty() && Q.back().second<=h[i])
Q.pop_back();
Q.push_back({i, h[i]});
}
}
if (!Q.empty())
return Q.back().first;
return cur.first;
}
bool solver(vector<int>& h, int k){
int n = h.size();
//不使用超能力
int farest = forword(h, k, 0);
if (farest+k>=n-1) return true;
int max_pos=farest;
//使用超能力跳到后面k个柱子上的最高处
for (int i=1; i<=k; ++i){
if (h[farest+i]>=h[max_pos])
max_pos = farest+i;
}
//不使用超能力
farest = forword(h, k, max_pos);
return farest==n-1;
}
int main(){
int T;
cin >> T;
while (T--){
int n, k;
cin >> n >> k;
vector<int> h(n);
for (int i=0; i<n; ++i) cin >> h[i];
if (solver(h, k))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
} #include<iostream>
(720)#include<vector>
#include <algorithm>
using namespace std;
typedef long long ll;
int main() {
int t;
cin >> t;
while (t--) {
ll n, k;
cin >> n >> k;
vector<ll> h(n);
for (ll i = 0; i < n; i++) {
cin >> h[i];
}
vector<vector<int>> dp(n, vector<int>(n));
vector<vector<int>> can_super(n, vector<int>(n));
dp[0][0] = 1;
int can_arrive = 0;
can_super[0][0] = 1;
for (ll i = 0; i < n; i++) {
for (ll j = i; j <= min(i + k, n - 1); j++) {
if (i == j && i != 0) {
for (int k = 0; k < i; k++) {
dp[i][j] = dp[i][j] | dp[k][j];
can_super[i][j] = can_super[i][j] | can_super[k][j];
}
}
if (h[j] > h[i] && can_super[i][i] == 1) {
dp[i][j] = 1;
can_super[i][j] = 0;
}
else if (h[j] <= h[i] && j!=i && dp[i][i] == 1) {
dp[i][j] = 1;
can_super[i][j] = can_super[i][i];
}
}
can_arrive += dp[i][n - 1];
/* if (can_arrive) {
break;
}*/
}
if (can_arrive) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
} import java.util.*;
public class Main{
public static boolean solution(int[] nums, int k){
int n = nums.length;
boolean[][] dp = new boolean[n][2];
dp[0][0] = true;
dp[0][1] = true;
for (int i = 1; i < n; i++){
for (int j = 1; j <= k && i - j >= 0; j++){
if (nums[i-j] >= nums[i]){
dp[i][0] |= dp[i-j][0];
dp[i][1] |= dp[i-j][1];
}
dp[i][1] |= dp[i-j][0];
}
}
return dp[n-1][0] || dp[n-1][1];
}
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int T = input.nextInt();
for (int i = 0; i < T; i++){
int n = input.nextInt();
int k = input.nextInt();
int[] nums = new int[n];
for (int j = 0; j < n; j++){
nums[j] = input.nextInt();
}
if(solution(nums,k)){
System.out.println("YES");
}else{
System.out.println("NO");
}
}
}
} function test (n, k, arrc) {
let map = new Map(), arr = [0].concat(arrc)
map[1] = true
let flag = 0, last = -1
for (let i = 2; i <= n; ++i) {
for (let j = i - 1; j >= i - k && j >= 1; --j) {
if (map[j] && arr[j] >= arr[i]) {
map[i] = true
if (i + k >= n) {
return true
}
flag = 0
last = -1
break
}
}
if (!map[i]) {
if (!flag) {
last = i
}
flag++
if (flag === k) {
break
}
}
}
if (last !== -1) {
let max = arr[last], index = -1
for (let i = last; i <= n && i <= last + k - 1; ++i) {
if (max <= arr[i]) {
max = arr[i]
index = i
}
}
if (index !== -1) {
map[index] = true
for (let i = index + 1; i <= n; ++i) {
for (let j = i - 1; j >= i - k && j >= 1; --j) {
if (map[j] && arr[j] >= arr[i]) {
map[i] = true
break
}
}
}
}
}
return !!map[n]
}
var readline = require('readline');
var rl = readline.createInterface({
input:process.stdin,
output:process.stdout
});
let inputs = [], pr = 0
rl.on("line", line => {
inputs.push(line.trim())
let n = +inputs[0]
if (inputs.length === (n*2+1)) {
for(var h = 0; h < n; h++){
var nu = inputs[h*2+1].split(' ').map(Number)[0]
var k = inputs[h*2+1].split(' ').map(Number)[1]
var arr = inputs[h*2+2].split(' ').map(Number)
console.log(test(nu, k, arr) ? 'YES' : 'NO')
}
}
});
/*
1
10 5
5 2 10 7 6 9 4 1 3 8
No
1
10 4
1 3 4 2 7 5 6 8 10 9
1
10 2
8 2 7 5 3 9 1 4 6 10
*/ public class Main_3 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int T = input.nextInt();
for (int i = 0; i < T; i++) {
int n = input.nextInt();
int k = input.nextInt();
int[] nums = new int[n];
// 完成nums的赋值,得到nums数组
for (int j = 0; j < n; j++) {
nums[j] = input.nextInt();
}
// print output
if (JumpPillar(n,k,nums)){
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
public static boolean JumpPillar(int n, int k, int[] nums) {
// nums数组表示的是每个柱子的高度 柱子数为n 最大跳跃距离为k 超能跳跃只能使用1次
// 由题知,柱子有n个,跳跃方式有2个,可由此确定状态
// 状态 f[n][2]:能否通过正常跳跃或者超能跳跃到达n
// f[n][0]:正常跳跃,f[n][1]:超能跳跃
boolean[][] dp = new boolean[n][2];
// initialization:在第一个柱子上不用跳直接可以到达
dp[0][0] = dp[0][1] = true;
/*
最后可以到达柱子n ==> 最后一跳只有两种可能,普通跳跃和超能跳跃
假设前面起跳位置为i,且最后一跳为超能跳跃,那么从第一个到第i个肯定全部是普通跳跃
假设前面起跳位置为i,且最后一跳为普通跳跃,那么前面就存在一个超能跳跃的可能
子问题:所以推广到任意一个j到i的位置,j可以使用两种到i的方式:普通或者超能
Note:如果j采用普通到达的,那么后续它可以使用超能,但是如果j是采用超能到达的,后续就不能使用超能了
*/
// from j to i
for (int i = 0; i < n; i++) {
// 对任意一个目标位置i,j的取值范围只能在[i-k, i-1]
for (int j = i-1; j>=0 && j >= i-k; j--) {
// j采用的是普通跳跃
if (dp[j][0]) {
// from j to i:满足高度可以普通到达,不满足可以超能跳跃
if (nums[j] >= nums[i]) {
dp[i][0] = true; // 普通
} else {
dp[i][1] = true; // 超能
}
}
// j采用超能跳跃
if (dp[j][1]) {
if (nums[j] >= nums[i]) {
dp[i][1] = true;
}
}
}
}
return dp[n-1][1];
}
} import java.util.*;
public class Main {
public static void main(String [] args) {
// 从前往后走,第一个柱子开始,统计后面k个柱子的最高柱子和小于等于当前柱子的最高柱子的坐标。
// 在代码中分别为 m_i, 和 n_i
// 如果没有小于等于当前柱子的,也就是没法走,尝试使用超能力,不能用了,就NO,能用就走到m_i
// 如果有小于等于当前柱子的,走到 n_i
// 总的来说是贪心的想法,如果能走,走能走的柱子中最高的;不能走,走包括不能走的最高的
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (int a = 0; a<t; a++) {
int n = sc.nextInt(),k = sc.nextInt();
int [] num = new int[n];
for (int i=0; i<n; i++) num[i] = sc.nextInt();
int cnt = 0,flag = 1;
for (int i=0; i<n; ) {
if (i == n-1) {
System.out.println("YES");
break;
}
int max = 0,nextMax = 0,m_i = -1,n_i = -1;
for (int j=i+1; j<=i+k&&j<n ; j++) {
if (num[j]<=num[i] && num[j]>nextMax) {
nextMax = num[j];
n_i = j;
}
if (num[j]>max) {
max = num[j];
m_i = j;
}
}
if (nextMax == 0) {
if (flag == 1) {
flag = 0;
i = m_i;
}
else {
System.out.println("NO");
break;
}
}
else {
i = n_i;
}
}
}
}
}