题解:P1410 子序列
StarsIntoSea · · 题解
很神的一道 DP!!
捋一下我们需要的状态:
- 第一个子序列的当前末尾元素。
- 第二个子序列的当前末尾元素。
- 第一个子序列的长度。
- 第二个子序列的长度。
但是
假设枚举到了第
发现如果枚举到了第
设状态
如果不能分配,
转移就是:
- 如果
a_i>a_{i-1} ,那么f(i,j) \leftarrow f(i-1,j-1) 。相当于插入末尾是a_{i-1} 的子序列中。 - 如果
a_i>f(i-1,j) ,那么f(i,i-j) \leftarrow a_{i-1} 。相当于插入末尾不是a_{i-1} 的子序列中。
时间复杂度
#include <bits/stdc++.h>
using namespace std;
const int N=2005;
int f[N][N];
int n,a[N];
void sol(){
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
memset(f,0x7f,sizeof f);
f[0][0]=a[0]=-1;
for(int i=1;i<=n;++i){
if(a[i-1]<a[i]) for(int j=1;j<=i;++j)
f[i][j]=f[i-1][j-1];
for(int j=1;j<i;++j) if(f[i-1][j]<a[i])
f[i][i-j]=min(f[i][i-j],a[i-1]);
}
puts(f[n][n/2]>1e9?"No!":"Yes!");
}
int main(){
while(scanf("%d",&n)==1) sol();
}