[luogu4728 HNOI2009] 双递增序列 (dp)

[luogu4728 HNOI2009] 双递增序列 (dp)

传送门

Solution

前几天刚做了类似题,这种将一个序列拆分为两个单调序列的题一般都是设\(dp[i]\)表示i为一个单调序列的末尾时,另一个序列的末尾是多少
然后应用贪心的思想,在这道题中就是让另一个序列末尾最小。
另外这道题还有长度的限制,不过由于总长知道,只需记其中一个的序列长度即可

Code

//By Menteur_Hxy
#include 
#include 
#include 
#include 
#include 
#include 
#define Re register
#define Ms(a,b) memset(a,(b),sizeof(a))
#define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
#define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)
using namespace std;

inline int read() {
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    return x*f;
}

const int N=2048,INF=0x3f3f3f3f;
int n,T;
int da[N],f[N][N];

int main() {
    T=read();
    while(T--) {
        n=read(); Fo(i,1,n) da[i]=read();
        Ms(f,0x3f); f[0][0]=da[0]=-1;
        Fo(i,1,n) Fo(j,0,i) {
            if(da[i]>da[i-1]) f[i][j]=min(f[i][j],f[i-1][j]);
            if(da[i]>f[i-1][i-j]) f[i][j]=min(f[i][j],da[i-1]);
        }
        puts(f[n][n/2]==INF?"No!":"Yes!");
    }
    return 0;
}
posted @ 2018-10-18 15:06 Menteur_Hxy 阅读( ...) 评论( ...) 编辑 收藏

你可能感兴趣的:([luogu4728 HNOI2009] 双递增序列 (dp))