P4728 [HNOI2009] 双递增序列
P4728 [HNOI2009] 双递增序列
题意简述:
给我们一个序列问我们是否可以将其划分为两个单调递增的子序列
Solution:
无比神奇的状态设计:记
那么我们就可以得到转移:
当
同理,当
注意:本文只是使用
也就是说,由于
然后最后答案的判断显然就是
写到这里我才发现我的注释貌似是假的
但是我题解写清楚了就行
Code:
#include<bits/stdc++.h> const int N=2005; const int inf=1e9; using namespace std; int f[N][N]; int a[N],lim[N]; int n; void init() { for(int i=0;i<N;i++)for(int j=0;j<N;j++)f[i][j]=inf; } void work() { cin>>n; init(); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } int lim=n>>1; f[1][1]=-1; for(int i=1;i<n;i++) { for(int len_U=1,len_V;len_U<=min(lim,i);len_U++) { len_V=i-len_U; // U: .....a[i] // V: .....f[i][len_V] // U: .....a[i],a[i+1] // V: .....f[i+1][len_V]() if(a[i]<a[i+1])f[i+1][len_U+1]=min(f[i+1][len_U+1],f[i][len_U]); // U: .....a[i](f[i+1][len_U]), // V: .....f[i][len_V],a[i+1] if(f[i][len_U]<a[i+1])f[i+1][len_V+1]=min(f[i+1][len_V+1],a[i]); } } printf(f[n][lim]==inf ? "No!\n" : "Yes!\n"); } int main() { int T; cin>>T; while(T--)work(); return 0; }