hdu 4960 Another OCD Patient (最短路 解法
http://acm.hdu.edu.cn/showproblem.php?pid=4960
2014 Multi-University Training Contest 9
Another OCD PatientTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) 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 By the way, if one Input
The input contains multiple test cases.
The first line of each case is an integer N (0 < N <= 5000), 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. Source
Recommend
|
题意:给出一个数列,包含n个数字v[i],再给出一个代价表a[j]。可以将v[]中相邻的j个数字合并(相加)为一个数,代价为a[j],每个v[i]最多被合并一次(新生成的数字不能被合并)。求 将v[]合并为一个回文串 所需的最小代价。
题解:
必须要把v[]合成回文串,所以最左边的若干个数合成,要等于最右边的若干个数合成。我们可以设两个下标l和r,表示左右各包括哪里了,若左边的和小于右边的和,l++,否则r--,直到左边的和等于右边的和,这时左右就分出了一组和相同的组合,我们只需要分别记录两边的元素个数。然后对[l+1,r-1]这个中间的区间,继续这个操作。最后中间可能会剩下一些数,将其元素个数记为mid。
然后我们就得到了很多组个数,用这些就可以算出答案。因为可能的合成方案就是我们这些组各合各的,最后就能组成一个回文串;或者其中相邻的若干组合成,因为各组本来就是对称相等的,相邻的组合成也是相等的;还有就是中间的mid和靠近中间的若干组合成。
这个最优结果怎么求呢?我想到了最短路。建个图,把合成操作当做路加入图中,i->j的路表示把第i+1,i+2,...j组合成为一组,路的长度为代价(可由各组的元素个数和求得,个数和可以先预处理,以便快速求得)。i->i+1代表这一组单独用,不合成,路的长度为代价。再弄一点把中间那块mid和其他的合成的路。
然后d[i]为0到i的最短路,也就是处理完第i组的最小消耗,d[处理完中间那块]就是答案。
不过要600ms,看来还是不如标准做法,我怕了,日后再学标准的。
代码:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
#define usll unsigned ll
#define mz(array) memset(array, 0, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(i=0;i<(n);i++)
#define FOR(i,x,n) for(i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) prllf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("1biao.out","w",stdout)
#define mp make_pair
#define pb push_back const int maxn=;
const int INF=*(1e9);
ll v[maxn];
int a[maxn];
int n;
//vector<int>SL,SR;
//int mid; const int maxm=maxn*maxn/;
struct edge {
int v,next;
int w;
} e[maxm];
int head[maxn],en; inline void add(const int &x,const int &y,const int &z) {
e[en].w=z;
e[en].v=y;
e[en].next=head[x];
head[x]=en++;
} bool f[maxn];///入队标志
int b[maxn];
int d[maxn];///b为循环队列,d为起点到各点的最短路长度
void spfa(int n) { ///0~n-1 共n个点
int i,k;
int st=, l=, r=; memset(f,,sizeof(f));
memset(b,,sizeof(b));
for(i=; i<n; i++)
d[i]=INF;
b[]=st;
f[st]=;
d[st]=;
while(l!=r) {
k=b[l++];
l%=n;
for(i=head[k]; i!=-; i=e[i].next)
if (d[k]+e[i].w < d[e[i].v]) {
d[e[i].v]=d[k] + e[i].w;
if (!f[e[i].v]) {
if(d[e[i].v]>d[b[l]]) {///SLF优化
b[r++]=e[i].v;
r%=n;
} else {
l--;
if(l==-)l=n-;
b[l]=e[i].v;
}
f[e[i].v]=;
}
}
f[k]=;
}
} void init() {
memset(head,-,sizeof(head));
en=;
} int suml[maxn],sumr[maxn];
int ql[maxn],qr[maxn],qn;
int farm() {
if(n==)return ;
int i,j,k; qn=;
int mid=;
int l=,r=n-;
int L=l,R=r;
ll sl=v[l],sr=v[r];
while(l<r) {
while(sl<sr) l++,sl+=v[l];
while(sl>sr) r--,sr+=v[r];
if(sl==sr && l<r) {
ql[qn]=l-L+;
qr[qn]=R-r+;
qn++;
l++;r--;
L=l;R=r;
sl=v[l];sr=v[r];
}
}
mid=R-L+;
// REP(i,qn)printf("%3d",ql[i]);
// puts("");
// REP(i,qn)printf("%3d",qr[i]);
// printf(" mid=%d\n",mid);
mz(suml);
mz(sumr);
for(i=; i<=qn; i++) {
suml[i]=suml[i-]+ql[i-];
sumr[i]=sumr[i-]+qr[i-];
}
init();
for(i=; i<qn; i++)
for(j=i+; j<=qn; j++) {
add(i,j, a[ suml[j] - suml[i] ] + a[ sumr[j]-sumr[i] ] );
}
for(i=; i<=qn; i++) {
add(i, qn+, a[ suml[qn] - suml[i] + sumr[qn] - sumr[i] + mid ]);
}
spfa(qn+);///0为起点,d[i]为搞完第i块的最少消耗
return d[qn+];
} int main() {
int i;
while(scanf("%d",&n)!=EOF) {
if(n==)break;
REP(i,n)scanf("%I64d",&v[i]);
FOR(i,,n)scanf("%d",&a[i]);
printf("%d\n",farm());
}
return ;
}
hdu 4960 Another OCD Patient (最短路 解法的更多相关文章
- HDU 4960 Another OCD Patient(记忆化搜索)
HDU 4960 Another OCD Patient pid=4960" target="_blank" style="">题目链接 记忆化 ...
- hdu 4960 Another OCD Patient(dp)
Another OCD Patient Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Ot ...
- HDU 4960 Another OCD Patient 简单DP
思路: 因为是对称的,所以如果两段是对称的,那么一段的前缀和一定等于另一段的后缀和.根据这个性质,我们可以预处理出这个数列的对称点对.然后最后一个对称段是从哪里开始的,做n^2的DP就可以了. 代码: ...
- HDU4960Another OCD Patient(间隙dp,后座DP)
Another OCD Patient Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Ot ...
- hdu 4960 记忆化搜索 DP
Another OCD Patient Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Ot ...
- HDU 4960 (水dp)
Another OCD Patient Problem Description Xiaoji is an OCD (obsessive-compulsive disorder) patient. Th ...
- HDU 4063 Aircraft --几何,最短路
题意: 给一些圆,要求从第一个圆的圆心走到最后一个圆的圆心,中间路径必须在某个圆内,求最短路径的长度. 解法: 易知要保持在圆内且路径最短,走两圆相交的点能使路径尽量短,所以我们找出所有的两圆相交的点 ...
- HDU 5637 Transform 单源最短路
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5637 题意: http://bestcoder.hdu.edu.cn/contests/contes ...
- HDU 4606 Occupy Cities (计算几何+最短路+最小路径覆盖)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题目:给出n个城市需要去占领,有m条线段是障碍物, ...
随机推荐
- 【bzoj3158】 千钧一发
http://www.lydsy.com/JudgeOnline/problem.php?id=3158 (题目链接) 题意 给出n个装置,每个装置i有一个特征值a[i]和一个能量值b[i],要求选出 ...
- 【poj1085】 Triangle War
http://poj.org/problem?id=1085 (题目链接) 题意 A,B两人玩游戏,在一个大三角形上放火柴,若A放上一根火柴后成功组成一个三角形,那么这个三角形就归属于A,并且A被奖励 ...
- 在VS里配置及查看IL
在VS里配置及查看IL 来源:网络 编辑:admin 在之前的版本VS2010中,在Tools下有IL Disassembler(IL中间语言查看器),但是我想直接集成在VS2012里使用,方法如下: ...
- Gulp.js----比Grunt更易用的前端构建工具
Gulp.js----比Grunt更易用的前端构建工具 Grunt一直是前端构建工具,然而他也不是毫无缺陷的,gulp的作者 Eric Schoffstall 在他介绍 gulp.js 的 prese ...
- Android程序设计-简单手机通讯录
在微信中,手机QQ中你会发现软件读取手机通讯录这个功能,这个功能使得软件更好的与手机联系人绑定,从而达到分享,拨打电话,读取用户信息等操作.下面我们将通过一个demo实现这个功能 首先我们看一下效果图 ...
- install docker on xubuntu
ref: https://docs.docker.com/engine/installation/linux/ubuntulinux/#/install-the-latest-version ps: ...
- dedecms /member/resetpassword.php SQL Injection Vul
catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 DEDEcms SQL注入漏洞导致可以修改任意用户密码 2. 漏洞触发条 ...
- Android知识体系图
网上看到,不知哪位大神总结的,存个档(需要放大网页才能看清)
- 加州大学伯克利分校Stat2.2x Probability 概率初步学习笔记: Section 4 The Central Limit Theorem
Stat2.2x Probability(概率)课程由加州大学伯克利分校(University of California, Berkeley)于2014年在edX平台讲授. PDF笔记下载(Acad ...
- Compiler Warning (level 3) C4800
#pragma warning( disable : 4800 ) // forcing bool 'true' or 'false' ,忽略4800 警告#pragma warning( disab ...