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. Android中日志信息的打印方式

    Android中日志信息的打印方式主要有以下7种: 1)System.out(i级别) 2)System.err(w级别) 3)Log.v 4)Log.d 5)Log.i 6)Log.w 7)Log. ...

  2. 用Delphi画圆角Panel的方法(使用CreateRoundRectRgn创造区域,SetWindowRgn显示指定区域)

    用Delphi画圆角Panel的方法: procedure TForm1.Button5Click(Sender: TObject);var fhr :Thandle;beginfhr:=Create ...

  3. 玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理

    原文:玩转Windows服务系列——Debug.Release版本的注册和卸载,及其原理 Windows服务Debug版本 注册 Services.exe -regserver 卸载 Services ...

  4. Samba &amp; Nginx - Resource temporarily unavailable

    先说说本人的开发环境:Win7 + Editplus + VMware(Centos+Samba+Nginx).用Samba在Centos上把web文件夹(如www)共享,然后在Win7上訪问这个文件 ...

  5. linux find命令强大之处

    find命令 find pathname -options [-print -exec -ok ...]   -print: find命令将匹配的文件输出到标准输出.   -exec: find命令对 ...

  6. struts2文件上传限制大小问题

    struts2默认文件上传大小为2M,如需改动默认大小,解决方法例如以下: <struts> <constant name="struts.multipart.maxSiz ...

  7. POJ 2826 An Easy Problem?! 好的标题

    受该两块木板以形成槽的效果.Q槽可容纳雨水多,注意雨爆跌,思想是非常easy,分类讨论是有点差. 1.假定两条线段不相交或平行,然后再装0: 2.有一个平行x轴.连衣裙0. 3.若上面覆盖以下的,装0 ...

  8. c语言太easy笔误的,这将做

    调试发现时间写的一样NB代码 test.c int add(string); int main() { char* p = "11222"; add(p); return 0; } ...

  9. TCP关闭过程

    状态迁移 . SO_LINGER/ SO_REUSEADDR TCP正常的关闭过程如下(四次握手过程): (FIN_WAIT_1) A ---FIN---> B(CLOSE_WAIT) (FIN ...

  10. WPF案例 (六) 动态切换UI布局

    原文:WPF案例 (六) 动态切换UI布局 这个Wpf示例对同一个界面支持以ListView或者CardView的布局方式呈现界面,使用控件ItemsControl绑定数据源,使用DataTempla ...