码迷,mamicode.com
首页 > 其他好文 > 详细

P1020 导弹拦截 /// DP Dilworth定理 LIS优化

时间:2018-07-13 20:46:33      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:play   view   while   tar   长度   c++   ide   std   使用   

题目大意:

https://www.luogu.org/problemnew/show/P1020

 

Dliworth有两个互相对偶的定理:
U的链划分使用的最少集合数,等于它的最大反链长度。(1)
U的反链划分使用的最少集合数,等于它的最大链长度。(2)

更详细的讲解

技术分享图片
#include <bits/stdc++.h>
using namespace std;
int a[100005];
int dp1[100005],dp2[100005];
int f1[100005],f2[100005];
/// 将 对应长度的最后一位的下标 存入f1[] f2[]中
/*  即若 2 2 4 3 对应下标为 0 1 2 3
    则长度为 1 2 3 时
    f[]对应为 f[1]   f[2]   f[3] 
                0      1      3  
                2      2 2    2 2 3
*/
int main()
{
    int k=0;
    while(~scanf("%d",&a[++k])) ;
    memset(f1,0,sizeof(f1)); memset(f2,0,sizeof(f2));
    int t1=0,t2=0;
    for(int i=1;i<k;i++) {
        dp1[i]=dp2[i]=1;
        for(int j=t1;j>0;j--) 
            if(a[f1[j]]>=a[i]) {
                dp1[i]=j+1; break;
            }
        t1=max(t1,dp1[i]);
        if(!f1[dp1[i]]) f1[dp1[i]]=i;
        else if(a[f1[dp1[i]]]<a[i]) f1[dp1[i]]=i;
        for(int j=t2;j>0;j--)
            if(a[f2[j]]<a[i]) {
                dp2[i]=j+1; break;
            }
        t2=max(t2,dp2[i]);
        if(!f2[dp2[i]]) f2[dp2[i]]=i;
        else if(a[f2[dp2[i]]]>a[i]) f2[dp2[i]]=i;
    }
    printf("%d\n%d\n",t1,t2);

    return 0;
}
View Code

 

P1020 导弹拦截 /// DP Dilworth定理 LIS优化

标签:play   view   while   tar   长度   c++   ide   std   使用   

原文地址:https://www.cnblogs.com/zquzjx/p/9307284.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!