• UVA103DAG上最长路径+字典序输出


    题目描述:

    给定n维的m个物品,按照各维长度严格递增的排序,求最长的序列,并按照字典序输出。

    例如n=4,(1 2 3 4)之后是(2,3,4,5)就可以。

    思维过程:

    《入门经典》上DAG模型。

    枚举状态结点时,出现了思维误区。想要把n维的n个长度滚动成n种状态点。

    上述考虑固然可以,但是不是n种状态点,因为是按顺序排列,所以是n!种,然而n《=30。

    后来想到了贪心的优化,我们的重点是一个能嵌套到另一个种,所以我们将变长从大到小排序。

    例如:a1<=a2<=a3<=a4<=a5

              b1<=b2<=b3<=b4<=b5

    假设把b3换到b2之前,如果b2>a3,那么固然b3>a2,所以排序后比较能保证能放就一定能放进

    算法分析:

    1、每个状态抽象成一个点,既求有向无环图上求最长路径

    2、没有终点,故枚举每个终点,结束点是每一个状态自成单点,既d[i]=0;

    3、为输出字典序,故枚举的是dp(i)以i为终点。

    4、调试的时候可以输出所有dp,方便模拟状态转移

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #define maxn 310//最多的状态数
    using namespace std;
    int d[maxn];
    int G[maxn][maxn];
    int m,n;
    struct Node{
        int a[15];//各个维度的长度
    }node[maxn];
    void print_path(int p){
        if (d[p]>1) printf("%d ",p);else printf("%d
    ",p);
        for(int i=1;i<=m;i++)
            if (d[i]+1==d[p] && G[p][i]==1) {print_path(i);break;}
    }
    void readin(){
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++)
                scanf("%d",&node[i].a[j]);
        sort(node[i].a+1,node[i].a+n+1);
        }
    }
    void builtG(){
        memset(G,0,sizeof(G));
        for(int i=1;i<=m;i++){
            for(int j=1;j<=m;j++){
                if (i==j) continue;
                int mark=1;
                for(int k=1;k<=n;k++)
                if (node[i].a[k]>=node[j].a[k]){mark=0;break;}
                if (mark) G[i][j]=1;
            }
        }
    }
    int dp(int i){
        int &ans=d[i];
        if (ans>0) return ans;
        ans=1;
        for(int j=1;j<=m;j++) if (G[i][j]) ans=max(ans,dp(j)+1);
        return ans;
    }
    void slove(){
        readin();
        builtG();
        memset(d,0,sizeof(d));
        int ans=-1;int p=-1;
        for(int i=1;i<=m;i++){
            int k=dp(i);
            if (ans<k) {ans=k;p=i;}
        }
        printf("%d
    ",ans);
        print_path(p);
        return ;
    }
    int main(){
        while(~scanf("%d%d",&m,&n)) slove();
        return 0;
    }
    

      

  • 相关阅读:
    读邮件正文
    收邮件
    算法 字符串转换为以为数组
    获取下拉框的值
    thinphp 模版标签中 除了volist 和 if 其余的标签中的变量不需要$符号
    php 时间戳处理 自定义时间戳
    jquery 根据json 生成数据 根据生成的数据选择对应的
    php qrcode 二维码 扫描后多行在软件中输出问题
    数组转换为字符串
    浏览器的同源策略
  • 原文地址:https://www.cnblogs.com/little-w/p/3446784.html
Copyright © 2020-2023  润新知