poj 2241 叠方块 基本动态规划

来源:互联网 发布:纯html商城源码 编辑:程序博客网 时间:2024/05/29 18:35

题意:给定n种block,每种block有无限多个,每个block有x, y, z三个属性

要求叠起来,使得在满足下面的长和宽严格大于上面的,情况下,高度最高


解法:

d[i] 表示 以第i个物品为能达到的最大高度

转移方程 d[i] = max{ d[i] ,  d[x] + height(x) 其中x要满足题目要求约束,遍取 0 - n - 1}

max(d[x])就是答案

#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int  INF = 990000000;const int maxn = 500 ;const int MAXN = maxn;///全局变量 和 函数//int T;int max(int a, int b){return a > b ? a : b;}int n;struct BLOCK{int x, y, z;bool operator < (const BLOCK& t) const{return (x * y) > (t.x * t.y);}};BLOCK blocks[maxn * 5];int d[maxn * 5];bool vis[maxn * 5];int cnt;int dp(int k){if (vis[k])return d[k];vis[k] = true;int i, j;int nowy, nowx, mh, maxheight;//以x, y为底mh = blocks[k].z;nowy = blocks[k].y;nowx = blocks[k].x;maxheight = mh;for (i = cnt - 1; i >= 0; i--){if ( (nowy < blocks[i].y && nowx < blocks[i].x) || (nowx < blocks[i].y && nowy < blocks[i].x) ) //写错了好几次{maxheight = max(maxheight, dp(i) + mh);}}return d[k] = maxheight;}int main(){///变量定义int i, j;int cases = 1;while(1){memset(vis, false, sizeof(vis));scanf("%d", &n);if (n == 0)break;cnt = 0;for (i = 0; i < n; i++){int x, y, z;scanf("%d %d %d", &x, &y, &z);blocks[cnt].x = x;blocks[cnt].y = y;blocks[cnt].z = z;cnt++;blocks[cnt].x = x;blocks[cnt].y = z;blocks[cnt].z = y;cnt++;blocks[cnt].x = y;blocks[cnt].y = z;blocks[cnt].z = x;cnt++;}//sort(blocks, blocks + cnt);//vis[0] = true;//d[0] = blocks[0].z;int ans = -1;for (i = cnt - 1; i >= 0; i--){ans = max(ans, dp(i));}printf("Case %d: maximum height = %d\n", cases++, ans);}///结束return 0;}


在此基础上上更改一下细节处理,对于block的面积从大到小进行排序

那么d[i] = max{ d[i],  d[k]  + height[k]  k < i }

速度会更快

#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int  INF = 990000000;const int maxn = 500 ;const int MAXN = maxn;///全局变量 和 函数//int T;int max(int a, int b){return a > b ? a : b;}int n;struct BLOCK{int x, y, z;bool operator < (const BLOCK& t) const{return (x * y) > (t.x * t.y);}};BLOCK blocks[maxn * 5];int d[maxn * 5];bool vis[maxn * 5];int cnt;int dp(int k){if (vis[k])return d[k];vis[k] = true;int i, j;int nowy, nowx, mh, maxheight;//以x, y为底mh = blocks[k].z;nowy = blocks[k].y;nowx = blocks[k].x;maxheight = mh;for (i = k - 1; i >= 0; i--){if ( (nowy < blocks[i].y && nowx < blocks[i].x) || (nowx < blocks[i].y && nowy < blocks[i].x) ) //写错了好几次{maxheight = max(maxheight, dp(i) + mh);}}return d[k] = maxheight;}int main(){///变量定义int i, j;int cases = 1;while(1){memset(vis, false, sizeof(vis));scanf("%d", &n);if (n == 0)break;cnt = 0;for (i = 0; i < n; i++){int x, y, z;scanf("%d %d %d", &x, &y, &z);blocks[cnt].x = x;blocks[cnt].y = y;blocks[cnt].z = z;cnt++;blocks[cnt].x = x;blocks[cnt].y = z;blocks[cnt].z = y;cnt++;blocks[cnt].x = y;blocks[cnt].y = z;blocks[cnt].z = x;cnt++;}sort(blocks, blocks + cnt); //先进行排序vis[0] = true;              //面积最大的作为顶的最大高度,记忆化搜索d[0] = blocks[0].z;int ans = -1;for (i = cnt - 1; i >= 0; i--){ans = max(ans, dp(i));}printf("Case %d: maximum height = %d\n", cases++, ans);}///结束return 0;}



原创粉丝点击