Another OCD Patient

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 716    Accepted Submission(s): 270

Problem Description
Xiaoji is an OCD (obsessive-compulsive disorder) patient. This morning, his children played with plasticene. They broke the plasticene into N pieces, and put them in a line. Each piece has a volume Vi. Since Xiaoji is an OCD patient,
he can't stand with the disorder of the volume of the N pieces of plasticene. Now he wants to merge some successive pieces so that the volume in line is symmetrical! For example, (10, 20, 20, 10), (4,1,4) and (2) are symmetrical but (3,1,2), (3, 1, 1) and
(1, 2, 1, 2) are not.



However, because Xiaoji's OCD is more and more serious, now he has a strange opinion that merging i successive pieces into one will cost ai. And he wants to achieve his goal with minimum cost. Can you help him?



By the way, if one piece is merged by Xiaoji, he would not use it to merge again. Don't ask why. You should know Xiaoji has an OCD.
Input
The input contains multiple test cases.



The first line of each case is an integer N (0 < N <= 5000), indicating the number of pieces in a line. The second line contains N integers Vi, volume of each piece (0 < Vi <=10^9). The third line contains N integers ai
(0 < ai <=10000), and a1 is always 0.



The input is terminated by N = 0.
Output
Output one line containing the minimum cost of all operations Xiaoji needs.
Sample Input
5
6 2 8 7 1
0 5 2 10 20
0
Sample Output
10
Hint
In the sample, there is two ways to achieve Xiaoji's goal.
[6 2 8 7 1] -> [8 8 7 1] -> [8 8 8] will cost 5 + 5 = 10.
[6 2 8 7 1] -> [24] will cost 20.
Author
SYSU
Source
题意:给出n个数,把这n个数合成一个对称的集合。第三行代表一次合成i个数须要花费a[i],求出最小的花费。
解题:先把n个数合成一个对称集合共k个块,再进行对称区间DP。

#include<stdio.h>
__int64 v[5005],a[5005],pre[5005],dp[5005];
void dfs(int l,int r)//分块,使[l,r]对称
{
int i=l,j=r;
__int64 suml=v[l],sumr=v[r];
while(i<j)
{
if(suml==sumr)
{
if(i+1<=j-1)dfs(i+1,j-1);
pre[l]=i; pre[j]=r;//区间最左最右块和相等
return ;
}
if(suml<sumr)suml+=v[++i];
else sumr+=v[--j];
}
pre[l]=r;//一个区间仅仅能合成一块
}
void count(int k)//分成k个块后。从最中间块向两边扩大范围进行DP,pre[i]表示从第一块到
{
int l, r,m;
if(k%2)
{
l=k/2; r=k/2+2; m=k/2+1;//m是最中间块
dp[m]=a[pre[m]-pre[m-1]];
}
else
{
l=k/2; r=k/2+1; m=l; dp[l]=0;
}
while(r<=k)
{
dp[r]=a[pre[r]-pre[l-1]];//合成一大块时
for(int tr=r,tl=l;m<tr;tr--,tl++)//在区间块找出相应的最小dp[r]
if(dp[r]>dp[tr-1]+a[pre[r]-pre[tr-1]]+a[pre[tl]-pre[l-1]])
dp[r]=dp[tr-1]+a[pre[r]-pre[tr-1]]+a[pre[tl]-pre[l-1]];
l--;r++;//向两边扩增
}
}
int main()
{
int n,i,k;
__int64 tk;
while(scanf("%d",&n)>0&&n)
{
for( i=1;i<=n;i++)scanf("%I64d",&v[i]);
for( i=1;i<=n;i++)scanf("%I64d",&a[i]);
dfs(1,n);
k=0; i=1;pre[0]=0;
while(i<=n)//把一整块缩成一个点,pre[k]变成前k个块共同拥有多少个数组成k块
{
tk=pre[i]-i+1; i=pre[i]+1; ++k; pre[k]=tk+pre[k-1];
}
count(k);
printf("%I64d\n",dp[k]);
}
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

HDU4960Another OCD Patient(间隙dp,后座DP)的更多相关文章

  1. hdu 4960 Another OCD Patient(dp)

    Another OCD Patient Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Ot ...

  2. [dp]HDOJ4960 Another OCD Patient

    题意: 给一个n, 第二行给n堆的价值v[i], 第三行给a[i].  a[i]表示把i堆合在一起需要的花费. 求把n堆变成类似回文的 需要的最小花费. 思路: ①记忆化搜索 比较好理解... dp[ ...

  3. [hdu4960]Another OCD Patient(区间dp)

    题意:给出n个数,把这n个数合成一个对称的集合.每个数只能合并一次. 解题关键:区间dp,dp[l][r]表示l-r区间内满足条件的最大值.vi是大于0的,所以可以直接双指针确定. 转移方程:$dp[ ...

  4. HDU 4960 Another OCD Patient 简单DP

    思路: 因为是对称的,所以如果两段是对称的,那么一段的前缀和一定等于另一段的后缀和.根据这个性质,我们可以预处理出这个数列的对称点对.然后最后一个对称段是从哪里开始的,做n^2的DP就可以了. 代码: ...

  5. HDU 4960 Another OCD Patient(记忆化搜索)

    HDU 4960 Another OCD Patient pid=4960" target="_blank" style="">题目链接 记忆化 ...

  6. DP套DP HDOJ 4899 Hero meet devil(国王的子民的DNA)

    题目链接 题意: 给n长度的S串,对于0<=i<=|S|,有多少个长度为m的T串,使得LCS(S,T) = i. 思路: 理解的不是很透彻,先占个坑. #include <bits/ ...

  7. hdu 4960 Another OCD Patient (最短路 解法

    http://acm.hdu.edu.cn/showproblem.php?pid=4960 2014 Multi-University Training Contest 9 Another OCD ...

  8. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  9. 377. Combination Sum IV——DP本质:针对结果的迭代,dp[ans] <= dp[ans-i] & dp[i] 找三者关系 思考问题的维度+1,除了数据集迭代还有考虑结果

    Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...

随机推荐

  1. 二进制搜索方法C++通用执行

    算法很easy.直接附着到代码它 #include <iostream> using namespace std; template<typename T> int binar ...

  2. thinkPHP 模板中的语法知识 详细介绍(十二)

    原文:thinkPHP 模板中的语法知识 详细介绍(十二) 本章节:介绍模板中的语法,详细的语法介绍 一.导入CSS和JS文件    ==>记住常量的是大写 1.css link .js  sc ...

  3. [C++]C++中的运行时类型检测

    Date:2014-1-3 Summary: 使用C++中的运行时类型检测.(文章重点在于记录本人的使用情况,并非深层讨论RTTI) Contents:写习惯C#的我,在C++依然存在哪些.NET的惯 ...

  4. DRP之Oracle_11g数据库安装

    不知道大家在安装了Oracle数据库的时候有没有这样或那样的困惑,今天这篇文章就把Oracle数据库的安装过程理一下,作为总结,方便以后的学习. 首先,将下载的两个文件放在一个目录下解压,然后打开文件 ...

  5. 那些年我们装过的数据库---盘点sqlserver2008安装时遇到的各种的问题(持续更新中)

    给自己安过sqlServer2008,也给好多同学安过sqlServer2008,期间遇到了好多不同的另人心烦的问题,在这里整理一下,(涉及到的部分方法是在网上找的,有些也没试过,仅仅是在这里整理一下 ...

  6. ZOJ 3794 Greedy Driver

    两次SPFA 第一关找:从1没有出发点到另一个点的多少是留给油箱 把边反过来再找一遍:重每一个点到终点最少须要多少油 Greedy Driver Time Limit: 2 Seconds       ...

  7. 三框架:使用数据源dbcp注意

    使用spring整合hibernate时间,需要使用该数据源,数据源使用apache的dbcp,使用dbcp当需要依靠pool的jar包.选择dbcp和pool当你需要注意. DBCP 2 compi ...

  8. Hasor:生命周期

    首先引用Wiki的介绍一下Hasor:     “Hasor是一款开源框架.它是为了解决企业模块化开发中复杂性而创建的.Hasor遵循简单的依赖.单一职责,在开发多模块企业项目中更加有调理.然而Has ...

  9. zoj1940(三维广搜)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=940 分析:三维其实就是六个方向地搜索,思维清晰且细心点,很快就AC了 ...

  10. ios多线程操作(五)—— GCD串行队列与并发队列

          GCD的队列能够分为2大类型,分别为串行队列和并发队列      串行队列(Serial Dispatch Queue):      一次仅仅调度一个任务,队列中的任务一个接着一个地运行( ...