`

ZOJ 2059 —— The Twin Towers 解题报告

J# 
阅读更多

据说很经典的DP题目。来源浙大月赛。

参考解题资料:http://allen303allen.bokee.com/viewdiary.19263200.html

 

自己的代码:

/*
ZOJ 2059 —— The Twin Towers
给定一个数字序列,问能不能构成2个序列,使得这两个序列的和相同,序列中的数字可以不用完。输出构成的2个序列的最大长度。
对于每个数字有3种选择,要么不放,要么放到较低的塔上,要么放到较高的塔上。
那么状态怎么表示呢?看到题目中塔的最大高度为2000,如果枚举这三种情况加100个数据就是3^100,肯定gg了。
从别人那学到的一种表示状态的方法,可以将2000看做最大高度差,那么共有2001个状态了。
对于每个状态的定义就是在高度差为i的情况下,较高的塔的高度是多少。
对于在高度差一定时,可以选择将当前数字添加到较高的塔上还是较低的塔上,然后就是结果,如果添加到较低的塔上会有2种情况:
1. 还是比高塔低   
2. 比高塔高了 , 更新新的高度差下的最大塔高, 
向高塔中添加此数,可以正常更新。
状态转移方程:h[i]为第i个数字,dp[i][j]为用到第i个数字时,高度差为j时较高的塔的高度 
    dp[i][j+h[i]] = max(dp[i][j+h[i], dp[i-1][j] + h[i]); //向高塔上添加此数。 
    if ( h[i] > j ) //h[i]比高度差j大,所以添加h[i]后就比dp[i-1][j]里的最高塔还高了。
        dp[i][h[i]-j] = max(dp[i][h[i]-j], dp[i-1][j] + h[i]-j);
    else           //h[i]比高度差j小 ,所以添加h[i]后较高的塔还较高, 
        dp[i][j-h[i]] = max(dp[i][j-h[i]], dp[i-1][j] ); 
做的时候运用循环数组,节省空间,注意初始化,在j高度差下,没有数字时要初始化成一个状态。 
*/
#include <iostream>
#include <cstdio>


int max(const int a, const int b)
{
    if ( a > b )
        return a;
    else
        return b;
}
int min(const int a, const int b)
{
    if ( a > b )    return b;
    else    return a;
} 
int main()
{
    int dp[2][2001], a[101];
    int n, i, j;
    int sum ;
    int t;
    while ( scanf("%d", &n ) != EOF && n != -1 )
    {
        sum = 0;
        for ( i = 1; i <= n; ++i )
        {    
            scanf("%d", &a[i]);
            sum += a[i];
        }
        sum = min(sum, 2000);
        for ( i = 0; i <= sum; ++i )
            dp[0][i] = -1;
        dp[0][0] = 0;
        dp[0][a[1]] = a[1];
        t = 0;
        for ( i = 2; i <= n; ++i )
        {
            t = 1-t;
            for ( j = 0; j <= sum; ++j )
                dp[t][j] = -1;
            for ( j = 0; j <= sum; ++j )
            {
                dp[t][j] = max(dp[t][j], dp[1-t][j]);
                if ( dp[1-t][j] == -1 )
                    continue;
                if ( j + a[i] <= sum ) //加到高的tower上 
                    dp[t][j+a[i]] = max(dp[1-t][j]+a[i], dp[t][j+a[i]]);     
                if ( j >= a[i] ) //加到低的上面比高的低 
                {
                    dp[t][j-a[i]] = max(dp[t][j-a[i]], dp[1-t][j]);
                }
                else //加到低的上面比高的高 
                {
                    dp[t][a[i]-j] = max(dp[t][a[i]-j], dp[1-t][j] + a[i]-j); 
                }
                
            }
            
        }
             
        
        
        if ( dp[t][0] > 0 )
            printf("%d\n",dp[t][0]);
        else
            printf("Sorry\n");      
    }
    return 0;
}
 

 

 

分享到:
评论

相关推荐

    ZOJ解题报告ZOJ解题报告

    ### ZOJ解题报告:深入理解与策略分析 #### 一、FireNet1002:网络流量分析与优化 在FireNet1002问题中,主要考察的是网络流量管理和优化技术。该问题通常涉及到如何在有限的带宽资源下,合理分配网络流量,以确保...

    zoj 解题报告 C语言

    【标题】"Zoj解题报告C语言"涵盖了在ZOJ(在线判题系统)上使用C语言解决算法竞赛问题的详细策略和方法。ZOJ是众多计算机编程竞赛平台之一,它提供了大量的算法题目供参赛者挑战,以提高编程技能和算法理解能力,...

    ZOJ完全解题报告,涵盖了几十道ZOJ上面的编程题,有很详细的解题方法供参阅

    【ZOJ完全解题报告】是一份专门为喜爱ACM(国际大学生程序设计竞赛)的同学们准备的资源,其中详尽地记录了解决ZOJ在线判题系统上几十道编程题目的全过程和方法。这份报告旨在帮助参赛者提高解题技巧,理解和掌握...

    浙大zoj月赛解题报告及代码

    【标题】"浙大ZOJ月赛解题报告及代码"揭示了这是一份与浙江大学ZOJ在线评测系统相关的竞赛编程资源,特别是针对月度竞赛的解题总结和实现代码。ZOJ,全称为Zhejiang University Online Judge,是浙江大学维护的一个...

    Zoj acm的AC解题报告

    【标题】"Zoj ACM的AC解题报告"揭示了关于在线判题系统ZOJ(Zhejiang University Online Judge)以及ACM(国际大学生程序设计竞赛)的相关知识。ZOJ是中国浙江大学主办的一个在线编程竞赛平台,它为参赛者提供了一个...

    zoj 1610 Count the Colors.md

    zoj 1610 Count the Colors.md

    zoj1027解题指南

    【标题】"ZOJ1027解题指南"是一个针对特定编程竞赛题目——ZOJ1027的解决方案集合。ZOJ,全称为“Zhejiang Online Judge”,是浙江大学主办的一个在线编程竞赛平台,提供了丰富的算法题目供参赛者练习和挑战。本解题...

    acm zoj1181 解题报告,用STL库

    acm zoj1181 解题报告,用STL库

    zoj1383_zoj1383_

    标题“zoj1383_zoj1383_”和描述中的“一个非常非常非常非常实用的zoj结题代码”暗示我们这可能是一个关于ZOJ(在线判题系统Zhejiang Online Judge)的编程挑战解决方案。ZOJ是一个为编程爱好者提供在线编程练习和...

    zoj 题库 详细解答 解题代码

    zoj 题库 详细解答 解题代码 该资源主要涵盖了 zoj 题库中的各种编程题目,涵盖了基本算法、数据结构、数学运算等多个方面的知识点。下面是对该资源中出现的知识点的详细解释: 1. 第一次 ACM 总结(7th ACM) 该...

    ACM训练必备POJ ZOJ题目分类及解题思路

    学习ACM程序设计的朋友一定要看,这是训练必备的POJ ZOJ题目分类及解题思路

    zoj 1002_zoj1002_

    【标题】"ZOJ 1002" 是一个在线编程竞赛题目,源自ZOJ(Zhejiang Online Judge),这是一个面向ACM/ICPC(国际大学生程序设计竞赛)的在线评测系统。题目编号1002,通常表示该题是ZOJ平台上的一个问题,可能涉及算法...

    zoj 1255 The Path.md

    zoj 1255 The Path.md

    zoj 1810 The Gourmet Club.md

    zoj 1810 The Gourmet Club.md

    zoj 2499 The Happy Worm.md

    zoj 2499 The Happy Worm.md

    zoj 2151 The Highest Profits.md

    zoj 2151 The Highest Profits.md

    zoj 源码700题

    【描述】"包含了zoj700多道题目的源代码,在做题时可以参考"说明这个压缩包中的源代码是解题思路和解决方案的实际体现,可以帮助用户理解不同问题的解决方法,从而在自己面对类似问题时提供借鉴。这些源代码可能涉及...

    ACM zoj题目 源代码

    1. **2059The Twin Towers.cpp**:这个题目可能涉及到几何问题,特别是空间结构的计算。可能需要处理二维或三维坐标,并找出某种最佳配置,例如建筑物的高度比较或覆盖面积计算。 2. **1752Rectangular Rectitude....

    ZOJ月赛 题解 (ZOJ Monthly, August 2014)

    通过深入研究20141007(ZOJ Monthly, August 2014)这个压缩包中的解题报告和代码,我们可以学习到上述及其他更多编程和算法技巧,同时了解高手们是如何思考和解决问题的,这对于提升编程思维和参加类似竞赛将大有裨益...

    zoj.rar_zoj_zoj4041

    现在,让我们转向解题的核心部分——源代码分析。在提供的压缩包中,有两个文件:4041.cpp和4041.exe。4041.cpp是源代码文件,它包含了实现ZOJ 4041解法的C++代码。我们需要查看函数定义、变量声明、主要逻辑流程...

Global site tag (gtag.js) - Google Analytics