风雪梦

柳絮因风起

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  4 Posts :: 76 Stories :: 3 Comments :: 0 Trackbacks

常用链接

留言簿

我参与的团队

搜索

  •  

最新评论

  • 1. re: LightOJ1080 Binary Simulation
  • 话说加个PushDown操作不就OK了咩?
  • --仗剑奔走天涯
  • 2. re: 正式开博
  • 加油!
  • --leafcloudsky
  • 3. re: 启航杯啊
  • 太屎了!!我竟然就这么的WA了两次,最终发现,第四题少了两句初始化,第五题把数组开错地方了,算法没问题,结果就这么从四题跌到二题,太伤不起了!!可怜我调spfa调了一晚上!!尼玛啊!!
  • --浅雨歌

阅读排行榜

评论排行榜

我承认,这道题我做了很久,大概是三天吧……所以应该把这道题答案放出来……

啃动态规划嘛,那肯定就是动态规划啦!

题目大意是有N种木块,每种无限个,有长宽高,任意两个当底,一个当高,把这些木块摞起来,上面的木块长和宽都必须比下面的小,问最高能摞多高?

好 吧,这道题刚开始看到的时候我果断看成了一个无限空间的背包问题,但是马上我就发现了bug,如果真的是当背包做,第二重循环怎么写啊……然后开始枚举第 二个状态……f[i]表示当第i个木块为顶时的最高高度,每一个木块都得比它下面的木块小,仔仔细细想想就能发现一个木块只能用三个,那么好吧,存储的时 候一个当成三个存好了……

遇到这种情况我喜欢用结构体,因为这样一个变量就可以存入一个木块的所有的参数,果断就是组合数,长宽高就那么存 就行了,而且长永远比宽长,为了保险,以所有木块的长为主进行排序。然后开始做,第i个木块为顶,然后开始扫它底下的木块,因为事先排过序了,在i下面的 木块只能是i之前的而且宽比i小的木块(实际上,愿意扫全场也行)。

最优子结构是当第i个为顶为最高的时候,i的下面一定存在一点k,当第 k个木块在最顶上的时候,使得高度最高,然后以k为最底,当第i个木块在最顶上的时候,使得高度最高,这样一来整体高度最高。说实话,我想过当摞了前i个 木块,使得高度最高的子结构,结果我就发现了每个木块都有三种摆放方式,然后就是一个大bug——根本无法实现好不好……

最优子结构找到了,然后就是写方程了哈

方程那段的代码:

if (f[i] < f[j] + a[i].g) f[i] = f[j] + a[i].g;

a[i].g是第i个的高,j表示的是i下面的那个,每一步都要有一个初始化,就是f[i] = a[i].g。

好了……写完了。

PS:其实这个灵感来自于磊哥的一个指导……原版是f[i, s]表示当第i个以s方式为顶的时候,最高的高度,然后我觉得木块的变化有点高深,就干脆把一个木块当成三个木块了。。。

特别鸣谢:磊哥ZLGG


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct data
{
    int x, y, z;
}a[100];
int n, i, j, tot, x, y, z, dp[100];
int max(int a, int b)
{
    if (a > b) return a;
    else return b;
}
int min(int a, int b)
{
    if (a < b) return a;
    else return b;
}
int cmp(data a, data b)
{
    return a.x > b.x;
}
void add(int x, int y, int z)
{
    tot++;
    a[tot].x = max(x, y);
    a[tot].y = min(x, y);
    a[tot].z = z;
    tot++;
    a[tot].x = max(x, z);
    a[tot].y = min(x, z);
    a[tot].z = y;
    tot++;
    a[tot].x = max(y, z);
    a[tot].y = min(y, z);
    a[tot].z = x;
}
int main()
{
    int t = 1;
    while (cin >> n && n != 0)
    {
        tot = 0;
        memset(dp, 0, sizeof(dp));
        for (i = 1; i <= n; i++)
        {
            cin >> x >> y >> z;
            add(x, y, z);
        }
        sort(a + 1, a + tot + 1, cmp);
        for (i = 1; i <= tot; i++) dp[i] = a[i].z;
        for (i = 2; i <= tot; i++)
          for (j = 1; j <= i; j++)
          {
              if (a[j].x > a[i].x && a[j].y > a[i].y)
              {
                  dp[i] = max(dp[i], dp[j] + a[i].z);
              }
          }
        int max = 0;
        for (i = 1; i <= tot; i++)
          if (dp[i] > max) max = dp[i];
        cout << "Case " << t++ << ": maximum height = " << max << endl;
    }
    return 0;
}
posted on 2012-11-09 01:14 浅雨歌 阅读(360) 评论(0)  编辑 收藏 引用 所属分类: DP

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理