一开始怎么都想不到思路。实际上,不能从LIS和DP的角度考虑,而是要从题目要求的东西的性质入手,再结合LIS在当前题目下的特殊性质,才能找到一个比较好的解法。
题目中,分割的每个序列的"值"都是LIS的长度,考虑一种极限情况:分成n个序列。在这种情况下,如果n为偶数,就得到了一个正确的结果("YES")。
接下来,问题就转化为了:如何将奇数下的情况转化为偶数的特殊情况?显然,一个奇数y=2*n+1,那么我们就考虑,能否单独拿出来一个数字,这个数字的值为1,再用两个或其他偶数个数字对它进行异或,从而得到答案("YES" or "NO")?
场上并没有想到偶数个数字什么时候可以"值"为1,这是因为下意识地将答案联系到了LIS的性质上,而没有将LIS的性质对于该题目的要求进行数学上的抽象。
其实很容易发现,如果两个相邻数字中,前面的数字大于等于后面的那个数字,这两个数字就可以用来对1进行异或,就得到了答案。
#include<cstdio> #include<iostream> using namespace std; const int MAXN=2e5; int a[MAXN]; int main(){ int t; scanf("%d",&t);; while(t--){ int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } if(n%2==0){ printf("YES\n"); continue; } bool flag=0; for(int i=1;i<=n-1;i++){ if(a[i]>=a[i+1]){ flag=1; } } if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }