la3637

来源:互联网 发布:ubuntu nodejs 升级 编辑:程序博客网 时间:2024/05/16 00:59

此题开始想的时候以为贪心可以过。。。果断想简单了。首先排序是肯定的。由于有三层。所以对于每一层的安排会影响后一层的决策 所以是dp

如何想呢,我参考来网上的解题报告:http://blog.csdn.net/wings_of_liberty/article/details/7522213

下面写下自己的想法。

当排序后。可以肯定最高的那本书是占用那一层的高度,但是至于那一层的宽度就暂时不知。但是我们可以认为最高的那一本书无论呢放哪一层都是同样的。所以我们就假设最高的那一本书放在第一层,那么我们就只要枚举第二层和第三层的高度来。但是还有宽度需要枚举啊。

这样我们考虑如果 从  第i到第n本书在同一层,第i-1本书在另一层,那么第1到i-2本书放在哪一层并不影响这两层中最高的书的高度。

那么对于有些高度是不是我们就不好判断放哪一层了? 所以我们选择枚举宽度。

我们用dp【i】【j】表示 第二层的宽度是i  第三层的宽度是j 其中的值代表二三层的高度和。那么最后求面积的时候就方便来只要将总宽度-i-j 然后三者比较就得出宽度了

高度呢 由于第一层高度已知+dp【i】【j】的值就是高度了。

然后我从宽度一直枚举过来就可以了

那么dp部分的可以这样写 其中sum是总宽度

        for(int k=1;k<n;k++)        {            //因为i,j到目前扫到的最长宽度也就tsum            tsum+=a[k].w;            for(int i=tsum;i>=0;i--)                for(int j=tsum;j>=0;j--)                {                    if(dp[i][j]==INF)continue;                    if(i==0)                    dp[i+a[k].w][j]=min(dp[i+a[k].w][j],dp[i][j]+a[k].h);                    else                    //在当前宽度加上一个w[i]                    if(i+a[k].w<=sum)                    dp[i+a[k].w][j]=min(dp[i+a[k].w][j],dp[i][j]);                    if(j==0)                    dp[i][j+a[k].w]=min(dp[i][j+a[k].w],dp[i][j]+a[k].h);                    else                    if(j+a[k].w<=sum)                    dp[i][j+a[k].w]=min(dp[i][j+a[k].w],dp[i][j]);                }        }

我试了下我的时间是1188 网上那种优化的代码貌似要2000上下 但是空间复杂度可以少些。

而且这次G++的时间比C++快不少 不知到为什么。。。。

原创粉丝点击