UVA-437 The Tower of Babylon (dp based on DAG)

Topic portal

Question: There are n (n<=30) types of cuboid squares. Given their length, width and height, each type of cuboid has an infinite number. Now these cuboids must be stacked into a tall tower. The requirement is the sum of the lengths of the following cuboids. The width must be strictly larger than the above cuboid, and you can rotate each cuboid arbitrarily. What is the highest height of towers you can pile up?

Idea: Since we can rotate the cuboid at will, we have 6 kinds of cuboid (arrangement of 3), we can get up to 180 squares, and then we can build a picture of this problem according to the relationship between length and width, and build it A directed acyclic graph (DAG), at this time we can get the result of topological sorting.

Code:

#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
//#define int long long
#define lowbit(x) x&-x
#define pii pair<int,int>
#define ull unsigned long long
#define pdd pair<double,double>
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read()
{
    
    
    int x=0,f=1;
    char ch=gc();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')
            f=-1;
        ch=gc();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=gc();
    }
    return x*f;
}
using namespace std;
const int N=4e4+666;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const double eps=1e-7;
const double PI=acos(-1);

struct node
{
    
    
    int a,b,h;
}p[N];

int head[N],to[N],val[N],nxt[N],tot,in[N];
void add(int u,int v,int w)
{
    
    
    nxt[++tot] = head[u];
    to[tot] = v;
    val[tot] = w;
    head[u] = tot;
}
int vis[N],dis[N];
int top()
{
    
    
    int res = -1;
    queue<int>q;
    q.push(0);
    mem(dis,0);
    while(!q.empty())
    {
    
    
        int u = q.front();
        q.pop();
        for(int i = head[u];i;i=nxt[i])
        {
    
    
            int v=to[i];
            in[v]--;
            dis[v] = max(dis[v],dis[u]+val[i]);
            res = max(res,dis[v]);
            if(in[v]==0)
                q.push(v);
        }
    }
    return res;
}
int solve()
{
    
    
    int n;
    int cas = 1;
    p[0].a=1e9;
    p[0].b=1e9;
    p[0].h=1e9;
    while(scanf("%d",&n)!=EOF)
    {
    
    
        if(!n)
            return 0;
        int m = 0;
        for(int i=1;i<=n;i++)
        {
    
    
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            p[++m] = {
    
    a,b,c};
            p[++m] = {
    
    a,c,b};
            p[++m] = {
    
    b,a,c};
            p[++m] = {
    
    b,c,a};
            p[++m] = {
    
    c,a,b};
            p[++m] = {
    
    c,b,a};
        }
        for(int i=0;i<=m;i++)
            for(int j=1;j<=m;j++)
                if(p[i].a>p[j].a&&p[i].b>p[j].b)
                {
    
    
                    add(i,j,p[j].h);
                    in[j]++;
                }
        printf("Case %d: maximum height = %d\n",cas++,top());
        mem(head,0);
        mem(to,0);
        mem(in,0);
        mem(val,0);
        mem(nxt,0);
        tot = 0;
    }
}

signed main()
{
    
    
//    int _;
//    cin>>_;
//    while(_--)
        solve();
    return 0;
}

Guess you like

Origin blog.csdn.net/Joker_He/article/details/111657283