HDU1069 Monkey and Banana(dp)

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

题意:给定n种类型的长方体,每个类型长方体无数个,要求长方体叠放在一起,且上面的长方体接触面积要小于下面,长宽也小于下面的长方体,求最高能叠放多高?

思路:首先每个长方体有三种情况可以作为底部,那么一共是3*n种类型的长方体,首先按长宽的大小排序,然后dp。dp[i]表示以第i块长方体为顶的最大高度,那么转移方程就是dp[i] = max(dp[i],dp[j] +  g[i]. h),形似一个LIS的dp,枚举 j 即可

AC代码:

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<queue>
 7 #include<cstdio>
 8 #include<unordered_map>
 9 #define inf 0x3f3f3f3f
10 using namespace std;
11 typedef long long ll;
12 const int maxn = 100;
13 int dp[maxn];
14 struct node{
15     int x,y,z;
16 }g[maxn];//设z为高度 ,x,y分别为长和宽
17 bool cmp(node a,node b){
18     if(a.x == b.x ) return a.y > b.y ;
19     return a.x > b.x ;
20 }
21 int m,n;
22 int main(){
23     int cnt = 1;
24     while(scanf("%d",&n)){
25         if(n == 0) break;
26         memset(dp,0,sizeof(dp));
27         for(int i = 1;i<=3*n;i+=3){
28             int x,y,z;
29             scanf("%d%d%d",&x,&y,&z);
30             g[i].x = x<y? x:y;
31             g[i].y = y>x? y:x;
32             g[i].z = z;
33             g[i+1].x = x<z? x:z;
34             g[i+1].y = z>x? z:x;
35             g[i+1].z = y;
36             g[i+2].x = y<z? y:z;
37             g[i+2].y = z>y? z:y;
38             g[i+2].z = x;
39         }
40         sort(g+1,g+1+3*n,cmp);
41         for(int i = 1;i<=3*n;i++) dp[i] = g[i].z ;
42         int ans = dp[1];
43         for(int i = 2;i<=3*n;i++){
44             for(int j = 1;j<i;j++){
45                 if(g[j].x > g[i].x && g[j].y > g[i].y ){
46                     dp[i] = max(dp[i],dp[j]+g[i].z );//形似一个LIS的dp
47                     ans = max(ans,dp[i]);
48                 }
49             }
50         }
51         printf("Case %d: maximum height = %d\n",cnt,ans);
52         cnt++;
53     }
54     return 0;
55 }

原文地址:https://www.cnblogs.com/AaronChang/p/12222620.html

时间: 2024-07-29 18:35:28

HDU1069 Monkey and Banana(dp)的相关文章

HDU1069 Monkey and Banana 【DP】

Monkey and Banana Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7816    Accepted Submission(s): 4028 Problem Description A group of researchers are designing an experiment to test the IQ of a

HDU1069 Monkey and Banana 简单dp

题意: 把给定的长方体(不限)叠加在一起,叠加的条件是,上面一个长方体的长和宽都比下面长方体的长和宽短: 求这些长方体能叠加的最高的高度.(其中(3,2,1)可以摆放成(3,1,2).(2,1,3)等). /* *********************************************** Author :devil Created Time :2015/12/7 20:38:42 ************************************************

HDU 1069 Monkey and Banana (动态规划)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1069 简单记录一下 思路:把长方体的各种摆法都存到数组里面,然后按照长宽排序,再dp即可 转移方程 dp[i]=max(dp[i],dp[t]+a[i].z) //dp里存的是高度,a[i].z是第i个的高度 1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cst

hdu 5623 KK&#39;s Number(dp)

问题描述 我们可爱的KK有一个有趣的数学游戏:这个游戏需要两个人,有N\left(1\leq N\leq 5*{10}^{4} \right)N(1≤N≤5∗10?4??)个数,每次KK都会先拿数.每次可以拿任意多个数,直到NN个数被拿完.每次获得的得分为取的数中的最小值,KK和对手的策略都是尽可能使得自己的得分减去对手的得分更大.在这样的情况下,最终KK的得分减去对手的得分会是多少? 输入描述 第一行一个数T\left( 1\leq T\leq 10\right)T(1≤T≤10),表示数据组

Ural 1353 Milliard Vasya&#39;s Function(DP)

题目地址:Ural 1353 定义dp[i][j],表示当前位数为i位时,各位数和为j的个数. 对于第i位数来说,总可以看成在前i-1位后面加上一个0~9,所以状态转移方程就很容易出来了: dp[i][j]=dp[i][j]+dp[i][j-1]+dp[i][j-2]+.......+dp[i][j-9]: 最后统计即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <

HDU 4908 (杭电 BC #3 1002题)BestCoder Sequence(DP)

题目地址:HDU 4908 这个题是从m开始,分别往前DP和往后DP,如果比m大,就比前面+1,反之-1.这样的话,为0的点就可以与m这个数匹配成一个子串,然后左边和右边的相反数的也可以互相匹配成一个子串,然后互相的乘积最后再加上就行了.因为加入最终两边的互相匹配了,那就说明左右两边一定是偶数个,加上m就一定是奇数个,这奇数个的问题就不用担心了. 代码如下: #include <iostream> #include <stdio.h> #include <string.h&g

Sicily 1146:Lenny&#39;s Lucky Lotto(dp)

题意:给出N,M,问有多少个长度为N的整数序列,满足所有数都在[1,M]内,并且每一个数至少是前一个数的两倍.例如给出N=4, M=10, 则有4个长度为4的整数序列满足条件: [1, 2, 4, 8], [1, 2, 4, 9], [1, 2, 4, 10], [1, 2, 5, 10] 分析:可用动态规划解题,假设dp[i][j],代表满足以整数i为尾数,长度为j的序列的个数(其中每一个数至少是前一个数的两倍).那么对于整数i,dp[i][j] 等于所有dp[k][j-1]的和,其中k满足:

UVA542 - France &#39;98(dp)

UVA542 - France '98(dp) 题目链接 题目大意:之前题目意思还以为看懂了,其实没看明白,它已经把各个选手分在各自所在的区域里面,这就意味着第一次的PK的分组已经确定,而且冠军必须是从两个左右分区出来的胜利者才有机会pk冠军. 解题思路:那么从1-16这个大的区间内诞生出来的冠军可能是来自左边,也可能是右边,然后再左边右边的子区间递归找出冠军.f[i][l][r]表示l-r这个区间的胜利者是i的概率,那么假设i在区间的最左边,f[i][l][r] = Sum(f[i][l][m

HDU 4968 Improving the GPA(dp)

HDU 4968 Improving the GPA 题目链接 dp,最大最小分别dp一次,dp[i][j]表示第i个人,还有j分的情况,分数可以减掉60最为状态 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int t, avg, n; double dp1[15][405], dp2[15][405]; double get(int x) { if