想看更多的解题报告: http://iyenn.com/rec/1824570.html
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:有n个砖块,每个砖块有长宽高,每个砖块有无限个,问叠起来最高有多高,一个砖块能够放在另一个砖块上的标准是
,上面砖块的长和宽都要小于下面砖块的长和宽
解题思路:类似于最长升序序列的DP,只不过需要变化一下,因为每个砖块无限个,立体的砖块,长和宽也可以作为高,而题目要求小于,
所以每个砖块分为3个不同的砖块,这样我们为了区分,将宽看做大的一边,长看做小的一边,这样就不用分为6个,再将所有砖块按照宽
来升序排序,接着用最长升序序列dp来比较就ok了
- /*
- Memory 256K
- Time 16MS
- */
- #include
- #include
- using namespace std;
-
- int max(int a,int b){
- return a>b?a:b;
- }
-
- int min(int a,int b){
- return a
- }
-
- class CBlock{ //砖块类
- public:
- int x,y,z; //分别代表长宽高
- };
-
- class CJob{
- private:
- int m_nBlockSum;
- CBlock *m_block;
- public:
- int Run();
- void AddBlock(int x,int y,int z);
- CJob(int x);
- ~CJob();
- };
-
- CJob::CJob(int x){
- m_nBlockSum = 0;
- m_block = new CBlock[3*x];
- }
-
- CJob::~CJob(){
- delete m_block;
- }
-
- void CJob::AddBlock(int x,int y,int z){
- m_block[m_nBlockSum].x = x;
- m_block[m_nBlockSum].y = y;
- m_block[m_nBlockSum].z = z;
- m_nBlockSum++;
- }
-
- int cmp(const CBlock &a, const CBlock &b){
- return a.x < b.x;
- }
-
- int CJob::Run(){
- sort(m_block,m_block+m_nBlockSum,cmp); //首先按长按顺时针排序,这样可以保证答案出来是一个最优值
- int ans = 0;
-
- int *dp = new int[m_nBlockSum*3];
-
- int i,j;
- for(i = m_nBlockSum - 1;i >= 0;i--){ //最长上升序列的dp
- dp[i] = m_block[i].z;
- for(j = i + 1;j < m_nBlockSum;j++){
- if(m_block[j].x > m_block[i].x && m_block[j].y > m_block[i].y){
- dp[i] = max(dp[j]+m_block[i].z,dp[i]);
- }
- }
- }
-
- for(i = 0;i < m_nBlockSum;i++){
- ans = max(ans,dp[i]);
- }
-
- delete dp;
- return ans;
- }
-
- int main(){
- int n,x,y,z,Case = 0;
- while(cin>>n){
- if(!n) break;
- CJob job(n);
- while(n--){
- cin>>x>>y>>z;
- job.AddBlock(min(x,y),max(x,y),z); //这里注意,我们标记小的为长,大的为宽
- job.AddBlock(min(y,z),max(y,z),x);
- job.AddBlock(min(x,z),max(x,z),y);
- }
- cout<<"Case "<<++Case<<": maximum height = "<
Run()< - }
- return 0;
- }
注:本文转载自blog.csdn.net的wangjian8006的文章"http://blog.csdn.net/wangjian8006/article/details/8901003"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
评论记录:
回复评论: