HDU 4001 To Miss Our Children Time (DAG上的DP,最长路)

有三种砖 , 要摞成一个Skyscraper ,给出长宽高类似矩形嵌套的部分序关系,根据这个关系给建立DAG图,不过这样要注意一下当砖的类型是0的时候有可能出现环的情况

用并查集维护下就好

#include <cstdio>
#include <cstring>
#define  max(a,b) (a>b?a:b)

typedef long long ll;
const int maxn=1050;
int n;
ll a[maxn],b[maxn];
int d[maxn];
ll c[maxn];
ll g[maxn][maxn];
ll dis[maxn];
int ring[maxn];

int find (int x)
{
    return ring[x]==x?x:ring[x]=find(ring[x]);
}

void build()
{
    memset (g , 0 , sizeof(g));
    for (int i=0 ; i<n ; ++i)
        ring[i]=i;
    for (int i=0 ; i<n ; ++i)
    {
        for (int j=0 ; j<n ; ++j)
        {
            if(i==j)continue;
            if(d[i]==0)//d=0
            {
                if(d[j]==0)if(a[i]==a[j] && b[i]==b[j])
                {
                    int fi=find(i);
                    int fj=find(j);
                    if(fi==fj)continue;
                    //g[fi][fj]+=c[j];
                    c[fi]+=c[j];
                    ring[fj]=fi;
                    continue;
                }
                if(a[i]>=a[j] && b[i]>=b[j])g[i][j]=c[i];
            }
            if(d[i]==1)
            {
                if(a[i]>=a[j] && b[i]>=b[j] && a[i]*b[i]>a[j]*b[j])g[i][j]=c[i];
            }
            if(d[i]==2)
            {
                if(a[i]>a[j] && b[i]>b[j])g[i][j]=c[i];
            }
        }
    }
}

ll dp(int x)
{
    if(dis[x]>0)return dis[x];
    ll ans=c[x];
    for (int i=0 ; i<n ; ++i)
    {
        if(ring[i]==i)
        if(g[x][i])ans=max(ans,dp(i)+c[x]);
        //if(g[i][x])ans=max(ans,dp(i)+g[i][x]);
    }
    //printf("d[%d]=%d\n",x,dis[x]=ans);
    return dis[x]=ans;
}

void debug ()
{
    puts("graph:");
    for (int i=0 ; i<n ;  ++i)
    {
        for (int j=0 ; j<n ; ++j)
        printf("%I64d  ",g[i][j]);
        puts("");
    }
    puts("c:");
    for (int i=0 ; i<n ; ++i)
    printf("%I64d %d~~~ " ,c[i],ring[i]);
    puts("");
}

int main ()
{
    while (scanf("%d",&n),n)
    {
        for (int i=0 ; i<n ; ++i)
        {
            scanf("%I64d%I64d%I64d%d",a+i , b+i , c+i , d+i);
            if(a[i]<b[i])a[i]^=b[i]^=a[i]^=b[i];
        }
        memset (dis , 0 , sizeof(dis));
        build();
        ll ans=0;
        //debug();
        for (int i=0 ; i<n ; ++i)
        {
            if(ring[i]==i)
                dis[i]=dp(i);
            ans=max(ans,dis[i]);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


 

HDU 上的类似题1069

数据比较小 用floyd 或DP都行

#include <cstdio>
#include <cstring>
#include <algorithm>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)

using namespace std;
const int maxn=95;
int dp[maxn];
int n;
int l[maxn],w[maxn],h[maxn];
int pin[maxn];
int I=0;
bool cmp(int a,int b)
{
    return l[a]>l[b] || (l[a]==l[b] && w[a]>w[b]);
}
int main ()
{
    int a,b,c;
    while (scanf("%d",&n),n)
    {
        for (int i=0 ; i<n ; ++i)
        {
            scanf("%d%d%d",&a,&b,&c);
            l[i]=max(a,b);w[i]=min(a,b);dp[i]=h[i]=c;
            l[i+n]=max(a,c);w[i+n]=min(a,c);dp[i+n]=h[i+n]=b;
            l[i+n+n]=max(b,c);w[i+n+n]=min(b,c);dp[i+n+n]=h[i+n+n]=a;
        }
        int N=3*n;
        for (int i=0 ; i<N ; ++i)
            pin[i]=i;
        sort (pin , pin+N , cmp);
        int ans=0;
        //for (int k=0 ; k<N ; ++k)
        for (int i=0 ; i<N ; ++i)
        {
            for (int j=i+1 ; j<N ; ++j)
            {
                //if(i==j)continue;
                if(l[pin[i]]>l[pin[j]] && w[pin[i]]>w[pin[j]])
                    dp[pin[j]]=max(dp[pin[j]],dp[pin[i]]+h[pin[j]]);
                ans=max(ans,dp[pin[j]]);
            }
        }
        /*for (int i=0 ; i<N ; ++i)
            printf("%d %d %d %d\n",l[i],w[i],h[i] , dp[i]);*/
        printf("Case %d: maximum height = %d\n",++I,ans);
    }
    return 0;
}


 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值