HDU1069 Monkey and Banana(动态规划)

Monkey and Banana

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1069

题目大意:

研究人员有$n$种类型的砖块,每种类型的砖块都有无限个。第i块砖块的长宽高分别用$xi,yi,zi$来表示。 同时,由于砖块是可以旋转的,每个砖块的3条边可以组成6种不同的长宽高。

在构建塔时,当且仅当A砖块的长和宽都分别小于B砖块的长和宽时,A砖块才能放到B砖块的上面,因为必须留有一些空间让猴子来踩。

你的任务是编写一个程序,计算猴子们最高可以堆出的砖块们的高度。

解题思路:

使用将砖的类型扩大到三倍,也就是说一块转三个不同大小的面都作为一次底。因为数据范围较小,可以记录哪个砖可以放在哪那块砖上面,然后dfs求解最大值,需要记忆化数组剪枝。

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define debug(a) cout<<#a<<":"<<a<<endl;
 4 typedef long long ll;
 5 const int N=1e6+7;
 6 const ll mod=1e9+7;
 7 int maxn,minn;
 8 struct aa{
 9     int a,b,w;
10 }node;
11 
12 vector<aa>arr;
13 vector<aa>mp[N];
14 int dp[N];
15 
16 int dfs(int a){
17     if(dp[a]){
18         return dp[a];
19     }
20     for(int i=0;i<mp[a].size();i++){
21         dp[a]=max(dfs(mp[a][i].a)+mp[a][i].w,dp[a]);    //第a块砖做底能垒到的高度的最大值 
22     }
23     return dp[a];
24 }
25 
26 
27 int main(){
28     int n,num=0;
29     int a,b,c;
30     while(cin>>n&&n){
31         num++;
32         arr.clear();
33         memset(dp,0,sizeof(dp));
34         maxn=0;
35         arr.push_back(node);
36         for(int i=1;i<=n;i++){
37             scanf("%d%d%d",&a,&b,&c);
38             node.a=a; node.b=b; node.w=c;        //一块砖的三种放法全部记录 
39             arr.push_back(node);
40             node.a=c; node.w=a;
41             arr.push_back(node);
42             node.b=a; node.w=b;
43             arr.push_back(node); 
44         }
45         for(int i=1;i<=3*n;i++){        //判断砖与砖之间的关系 
46             mp[i].clear();
47             for(int j=1;j<=3*n;j++){
48                 if(arr[i].a>arr[j].a&&arr[i].b>arr[j].b){
49                     node.a=j;
50                     node.w=arr[j].w;
51                     mp[i].push_back(node);
52                 }
53                 else if(arr[i].b>arr[j].a&&arr[i].a>arr[j].b){
54                     node.a=j;
55                     node.w=arr[j].w;
56                     mp[i].push_back(node);
57                 }
58             }
59         }
60         for(int i=1;i<=3*n;i++){    //每一块砖都做一次底 
61             maxn=max(maxn,arr[i].w+dfs(i));
62         }
63         printf("Case %d: maximum height = %d\n",num,maxn);
64     }
65     
66 
67 
68     return 0;
69 }
posted @ 2020-04-05 14:13  yya雨  阅读(162)  评论(0编辑  收藏  举报