题目描述

小明很喜欢摆积木,现在他正在玩的积木是由N个木块组成的,他想用这些木块搭出两座高度相同的塔,一座塔的高度是搭建它的所有木块的高度和,并且一座塔至少要用一个木块。每个木块只能用一次,也可以不用。目前已知每块木块的高度,小明想知道在最终两个塔的高度相同的情况下,他所能搭的塔的最大高度是多少,你能帮助他吗?

输入输出格式

输入格式:

第一行为一个整数N,表示木块个数。

第二行是N个整数,表示N块木块的高度。

【数据规模】

对于100%的数据,N≤50,每块木块的高度h满足1≤h≤500000,所有木块的高度总和≤500000。

输出格式:

仅一个整数,表示能搭建的塔的最大高度,若不能搭建两座相同高度的塔,则输出“-1”。

输入输出样例

输入样例#1:

3

2 3 5

输出样例#1:

5

Solution

这道题想了我好一会啊,一直往状压方面凑...不过一开始忽略了一个条件,所有的木块都要放完.

状态需要联系到差值,这类要求相等的题目似乎都可以和差值联系上.

定义状态:

\[f[i][j]
\]

  1. i代表当前到了第 i 个木块,然后 j 代表此时较小值与较大值的差值.
  2. f[i][j] 保存的是当前较小值的值.

状态转移

  1. 一个基本的方向:我们让当前的较小值取更大,更接近较大值.
  2. 当前这个木块有两个走向:

    给较小值:

    此时我们由前一个状态走过来话,他们的差值会变得更小.

    同时这个较小值也会变大.

    此时我们的状态转移即为:
    \[f[i][j]=max(f[i-1][j],f[i-1][j+c[i]]+c[i]);
    \]

    给较大值

    此时同理上方,但是我们需要比较当前这个 j 和 c[i] 的大小.

    因为我们 f 数组记录的是较小值.所以不可能之前的差值为负数.

    此时状态转移为:

    1.c[i] 大于 j

    \[f[i][j]=max(f[i][j],f[i-1][c[i]-j]+c[i]-j);
    \]

    1. j 小于 c[i]

    \[f[i][j]=max(f[i][j],f[i-1][j-c[i]]);
    \]

于是我们转移便已完成.

不过这道题目还有一个坑点,就是极小值必须赋成很小.

否则会 WA 的很惨.

代码

#include<bits/stdc++.h>
using namespace std;
const int inf=19260817;
const int maxn=51;
int f[maxn][maxn*10000],sum;
int n,c[maxn*2],ans=-1;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)
cin>>c[i],c[i+n]=c[i],sum+=c[i];
for(int i=1;i<=n;i++)
for(int j=0;j<=sum;j++)
f[i][j]=-inf;
f[1][0]=0,f[1][c[1]]=0;
for(int i=2;i<=n;i++)
for(int j=0;j<=sum;j++)
{
f[i][j]=f[i-1][j];
f[i][j]=max(f[i][j],f[i-1][j+c[i]]+c[i]);
if(j<c[i])
f[i][j]=max(f[i][j],f[i-1][abs(j-c[i])]+c[i]-j);
else
f[i][j]=max(f[i][j],f[i-1][j-c[i]]);
}
if(f[n][0]!=0)
ans=f[n][0];
cout<<ans<<endl;
return 0;
}

P1651 塔 (动态规划)的更多相关文章

  1. [bzoj1019][SHOI2008]汉诺塔 (动态规划)

    Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操 ...

  2. hdu 2084 数塔(动态规划)

    本题是一个经典的动态规划题. 直接利用记忆化搜索:见图解 Ac code : #include<stdio.h> #include<string.h> #define max( ...

  3. luogu P1651 塔

    题目描述 小明很喜欢摆积木,现在他正在玩的积木是由N个木块组成的,他想用这些木块搭出两座高度相同的塔,一座塔的高度是搭建它的所有木块的高度和,并且一座塔至少要用一个木块.每个木块只能用一次,也可以不用 ...

  4. P1651 塔

    ----------------- 链接:Miku ----------------- 这是一道dp题,我么很容易发现这点. 数据范围很大,如果直接用两个塔的高度当状态,很危险,我们就必须要考虑一下优 ...

  5. 杭电ACM分类

    杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze ...

  6. 转载:hdu 题目分类 (侵删)

    转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012. ...

  7. c++ 动态规划(数塔)

    c++ 动态规划(dp) 题目描述 观察下面的数塔.写一个程序查找从最高点到底部任意位置结束的路径,使路径经过数字的和最大. 每一步可以从当前点走到左下角的点,也可以到达右下角的点. 输入 5 13 ...

  8. [ACM_动态规划] 数字三角形(数塔)

    递归方法解决数塔问题 状态转移方程:d[i][j]=a[i][j]+max{d[i+1][j],d[i+1][j+1]} 注意:1\d[i][j]表示从i,j出发的最大总和;2\变界值设为0;3\递归 ...

  9. HDU 2084 数塔(动态规划)

    数塔 http://acm.hdu.edu.cn/showproblem.php?pid=2084 Problem Description 在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描 ...

随机推荐

  1. SVN的两种存储方式FSFS和BDB比较【转】

    版本库数据存储 在Subversion1.2中,版本库中存储数据有两种方式.一种是在Berkeley DB数据库中存储数据:另一种是使用普通的文件,使用自定义格式.因为Subversion的开发者称版 ...

  2. win7 ghost 纯净版最新系统下载

    这个系统是WIN7系统GHOST版装机旗舰版 SP1,更新了系统补丁到2016-02(可通过微软漏洞扫描和卫士漏洞扫描),升级Internet Explorer为IE9,增加数款驱动的支持,支持最新的 ...

  3. VS2010中C++ 出现fatal error LNK1169: 找到一个或多个多重定义的符号

    一般是函数重定义造成的 例如定义了两个 sum(x,y)函数

  4. (九)maven之聚合多模块

    聚合项目 一些开源项目,都会把自己的源代码公开到github之类的网站上,我们通过下载其代码,在本地执行maven install,可以把代码编译成jar包安装到本地仓库.而一个项目通常有多个模块,比 ...

  5. Xcode5 如何添加一个Github/Repository 并且Checkout

    1. 添加一个Account  也就是添加一个 Repository. In Xcode, choose Xcode > Preferences, and click Accounts. Pre ...

  6. 【Selenium-WebDriver问题点】driver和浏览器版本之间的兼容性问题

    今天把手头有的一些关于selenium测试的资源整理了一下,分享出来. 1. 所有版本chrome下载 是不是很难找到老版本的chrome?博主收集了几个下载chrome老版本的网站,其中哪个下载的是 ...

  7. 油猴Tampermonkey 全局函数 它的注入函数都在 onload里面,直接写函数 都是内部函数,外部要是调用,就要挂靠到window上

    油猴Tampermonkey 全局函数 它的注入函数都在 onload里面,直接写函数 都是内部函数,外部要是调用,就要挂靠到window上 window.like111 = function (){ ...

  8. js获得本季度的开始日期 结束日期

    var now = new Date(); //当前日期var nowMonth = now.getMonth()+1; //当前月var nowYear = now.getFullYear(); / ...

  9. oracle中group by的高级用法

    简单的group by用法 select c1,sum(c2) from t1 where t1<>'test' group by c1 having sum(c2)>100; ro ...

  10. ES6新数据类型map与set

    一.map,简单的键值对映射,具有很快的查找速度 1. 初始化map,map的键名可以使用其他数据类型,对象的属性名只能使用字符串或symbol 使用二维数组 var m = new Map([['n ...