两次dp,一次从左到右可以到的位置记为true,一次从右到左可以到的位置记为true。
如果从左到右可以直接到尾巴肯定YES,否则如果用一次超能力到达的位置可以到尾巴也YES。
#include <bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { int n,k; cin>>n>>k; int h[n]; for(int i=0;i<n;i++) cin>>h[i]; bool dp[n]; memset(dp,false,sizeof dp); dp[0]=true; for(int i=0;i<n-1;i++){ for(int j=i+1;j<=min(n-1,i+k);j++){ if(dp[i]&&h[i]>=h[j]) { dp[j]=true; } } } // 不用超能力也可以 if(dp[n-1]==true) { cout<<"YES"<<endl; } else { bool redp[n]; memset(redp,false,sizeof redp); redp[n-1]=true; for(int i=n-1;i>0;i--) { for(int j=i-1;j>=max(0,i-k);j--) { if(redp[i]&&h[j]>=h[i]) { redp[j]=true; } } } int f=0; // 使用超能力 for(int i=0;i<n-1&&f==0;i++) { if(dp[i]==false) continue; for(int j=i+1;j<=min(n-1,i+k);j++){ if(redp[j]) { f=1; break; } } } if(f==1) cout<<"YES"<<endl; else cout<<"NO"<<endl; } } return 0; }