zoukankan      html  css  js  c++  java
  • Uva 437 DAG上的dp

    题意:

    有n种长宽高为x,y,z的砖头,每种都有无数个。砖头可以用不同姿势的方向来盖。

    砖头a以某种姿势可以盖在砖头b上,当且仅当a的底部的长宽都要比b的底部长宽要小。

    问最高可以建多高?

    思路:

    其实就是白书DAG上dp一个基础题。归结为矩形嵌套问题,状态转移和三角形状态转移一样。

    对于一个x,y,z砖头,它可以有3中姿势放置。注意矩形可以旋转90度,所以宽高位置没影响,主要在不同值上。

     (前两个为地面,后一个为高)

    x, y, z

    x, z, y

    y, z, x

    把每种姿势都记录下来,变成了有3*n种固定姿势的砖头。

    然后建图, 注意双向图,mp[i][j] = true,表示砖头i可以盖在砖头j上,反之亦然,从外圈到内圈

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 100;
    bool mp[maxn][maxn];
    int d[maxn];
    int n;
    
    struct Node {
        int x,y,h;
        }node[maxn];
    
    bool check(int i,int j) {
        return node[i].x<node[j].x && node[i].y<node[j].y ||
            node[i].x < node[j].y &&node[i].y < node[j].x;
        }
    
    int dfs(int u) {
        if(d[u]!=-1) {
            return d[u];
        }
        //当前的自己的高度
        d[u] = node[u].h;
        for(int i = 0; i < n; i++) {
            if(mp[u][i]) {
                //d[u] = max(d[u],dfs(i)+node[u].h)
                //一开始这样写,循环每次循环d[u]就变了,所以加的不是这一层的高度,而是累加了
                //遍历当前u为起点的所有可到达的下一个"状态"
                d[u] = max(d[u],dfs(i)+node[u].h);
    
            }
        }
        return d[u];
    }
    
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        int casen;
        casen = 0;
        while(scanf("%d",&n)&&n) {
            for(int i = 0; i < n; i++) {
                scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].h);
                node[n+i].x = node[i].y;
                node[n+i].y = node[i].h;
                node[n+i].h = node[i].x;
                node[n*2+i].x = node[i].x;
                node[n*2+i].y = node[i].h;
                node[n*2+i].h = node[i].y;
            }
    
            n *= 3;
            memset(mp,false,sizeof(0));
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < n; j++) {
                    mp[i][j] = check(i,j);
                }
            }
    
    
            memset(d,-1,sizeof(d));
            int ans = 0;
            for(int i = 0; i < n; i++) {
                ans = max(ans,dfs(i));
            }
    
            printf("Case %d: maximum height = %d
    ",++casen,ans);
        }
        return 0;
    }
  • 相关阅读:
    04_面向对象之多态
    03_面向对象之继承
    02_对象和对象封装
    01_什么是类
    01_函数对象
    python_IO操作之B模式介绍
    python_IO操作之rwa模式介绍
    python之初始IO操作01
    Flink基础(十七): Flink CEP 简介
    解决:UserBehavior is already defined as case class UserBehavior
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/7216270.html
Copyright © 2011-2022 走看看