据说很经典的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解题报告C语言"涵盖了在ZOJ(在线判题系统)上使用C语言解决算法竞赛问题的详细策略和方法。ZOJ是众多计算机编程竞赛平台之一,它提供了大量的算法题目供参赛者挑战,以提高编程技能和算法理解能力,...
【ZOJ完全解题报告】是一份专门为喜爱ACM(国际大学生程序设计竞赛)的同学们准备的资源,其中详尽地记录了解决ZOJ在线判题系统上几十道编程题目的全过程和方法。这份报告旨在帮助参赛者提高解题技巧,理解和掌握...
### ZOJ解题报告:深入理解与策略分析 #### 一、FireNet1002:网络流量分析与优化 在FireNet1002问题中,主要考察的是网络流量管理和优化技术。该问题通常涉及到如何在有限的带宽资源下,合理分配网络流量,以确保...
【标题】"浙大ZOJ月赛解题报告及代码"揭示了这是一份与浙江大学ZOJ在线评测系统相关的竞赛编程资源,特别是针对月度竞赛的解题总结和实现代码。ZOJ,全称为Zhejiang University Online Judge,是浙江大学维护的一个...
【标题】"Zoj ACM的AC解题报告"揭示了关于在线判题系统ZOJ(Zhejiang University Online Judge)以及ACM(国际大学生程序设计竞赛)的相关知识。ZOJ是中国浙江大学主办的一个在线编程竞赛平台,它为参赛者提供了一个...
zoj 1610 Count the Colors.md
【标题】"ZOJ1027解题指南"是一个针对特定编程竞赛题目——ZOJ1027的解决方案集合。ZOJ,全称为“Zhejiang Online Judge”,是浙江大学主办的一个在线编程竞赛平台,提供了丰富的算法题目供参赛者练习和挑战。本解题...
acm zoj1181 解题报告,用STL库
zoj 题库 详细解答 解题代码 该资源主要涵盖了 zoj 题库中的各种编程题目,涵盖了基本算法、数据结构、数学运算等多个方面的知识点。下面是对该资源中出现的知识点的详细解释: 1. 第一次 ACM 总结(7th ACM) 该...
学习ACM程序设计的朋友一定要看,这是训练必备的POJ ZOJ题目分类及解题思路
【标题】"ZOJ 1002" 是一个在线编程竞赛题目,源自ZOJ(Zhejiang Online Judge),这是一个面向ACM/ICPC(国际大学生程序设计竞赛)的在线评测系统。题目编号1002,通常表示该题是ZOJ平台上的一个问题,可能涉及算法...
zoj 1255 The Path.md
标题“zoj1383_zoj1383_”和描述中的“一个非常非常非常非常实用的zoj结题代码”暗示我们这可能是一个关于ZOJ(在线判题系统Zhejiang Online Judge)的编程挑战解决方案。ZOJ是一个为编程爱好者提供在线编程练习和...
zoj 1810 The Gourmet Club.md
zoj 2151 The Highest Profits.md
zoj 2499 The Happy Worm.md
【描述】"包含了zoj700多道题目的源代码,在做题时可以参考"说明这个压缩包中的源代码是解题思路和解决方案的实际体现,可以帮助用户理解不同问题的解决方法,从而在自己面对类似问题时提供借鉴。这些源代码可能涉及...
1. **2059The Twin Towers.cpp**:这个题目可能涉及到几何问题,特别是空间结构的计算。可能需要处理二维或三维坐标,并找出某种最佳配置,例如建筑物的高度比较或覆盖面积计算。 2. **1752Rectangular Rectitude....
通过深入研究20141007(ZOJ Monthly, August 2014)这个压缩包中的解题报告和代码,我们可以学习到上述及其他更多编程和算法技巧,同时了解高手们是如何思考和解决问题的,这对于提升编程思维和参加类似竞赛将大有裨益...
现在,让我们转向解题的核心部分——源代码分析。在提供的压缩包中,有两个文件:4041.cpp和4041.exe。4041.cpp是源代码文件,它包含了实现ZOJ 4041解法的C++代码。我们需要查看函数定义、变量声明、主要逻辑流程...