【dp】石子合并问题
来源:互联网 发布:mac win7 0x80070570 编辑:程序博客网 时间:2024/05/16 14:54
问题描述:
在一个圆形操场的四周摆放着n 堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻 的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。
编程任务:
试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。
数据输入:
包含两行,第1 行是正整数n(1<=n<=100),表示有n堆石子。
第2行有n个数,分别表示每堆石子的个数。
结果输出:
输出两行。
第1 行中的数是最小得分;第2 行中的数是最大得分。
样例:
4
4 4 5 9
43
54
核心思想
f[i,j]=min{f[i,k]+f[p,j-1]+sum[i,(i+j-2)modn+1](2<=j<=n,1<=i<=n,1<=k<=j-1,p=(i+k-1)mod n+1)},前i个石子合并j次的最小合并/最大合并,环
var a:array[1..200] of longint; n,tot:longint; f:array[1..200,1..200] of longint; sum:array[1..200,1..200] of longint;procedure init;var i,j,k:longint; begin tot:=0; readln(n); fillchar(sum,sizeof(sum),0); for i:= 1 to n do begin read(a[i]); tot:=tot+a[i]; end; for i:= 1 to n do for j:= i to n do if i=j then sum[i,j]:=a[i] else if j>i then sum[i,j]:=sum[i,j-1]+a[j]; for i:= 2 to n do begin for j:= 1 to i-1 do if i=j+1 then sum[i,j]:=tot else sum[i,j]:=tot-sum[j+1,i-1]; {<环上的sum处理>} end; end;procedure main;var i,j,k,p:longint; data,ans:longint; begin fillchar(f,sizeof(f),100); for i:= 1 to n do f[i,1]:=a[i]; for j:= 2 to n do for i:= 1 to n do for k:= 1 to j-1 do begin p:=(i+k-1) mod n +1 ;{<处理环>} data:=f[i,k]+f[p,j-k]+sum[i,(i+j-2) mod n+1]; if f[i,j]>data then f[i,j]:=data; end; ans:=maxlongint; for i:= 1 to n do if f[i,n]<ans then ans:=f[i,n]; writeln(ans-tot); fillchar(f,sizeof(f),0); for i:= 1 to n do f[i,1]:=a[i]; for j:= 2 to n do for i:= 1 to n do for k:= 1 to j-1 do begin p:=(i+k-1) mod n +1 ; data:=f[i,k]+f[p,j-k]+sum[i,(i+j-2) mod n +1]; if f[i,j]<data then f[i,j]:=data; end; ans:=0; for i:= 1 to n do if f[i,n]>ans then ans:=f[i,n]; writeln(ans-tot); end;begin assign(input,'p35.in');reset(input); assign(output,'p35.out');rewrite(output); init; main; close(input);close(output);end.题目来源:《算法设计与分析》第三章动态规划
- 【dp】石子合并问题
- dp 石子合并问题
- 石子合并问题(dp)
- ACM DP 石子合并问题
- 环形石子合并问题 - 经典DP问题
- NKOJ 1137 石子合并问题 (区间dp)
- 经典问题石子合并(环形)DP
- 石子合并问题 (区间dp)
- 石子合并问题(区间DP)
- ssl1597-石子合并问题【区间dp练习】
- 石子合并 (区间DP)
- 石子合并 (区间dp)
- 石子合并(区间dp)
- <区间DP> 石子合并
- noip1995石子合并-dp
- [区间DP]石子合并
- 合并石子,区间DP
- DP 合并石子
- 目前可用的通用DNS
- C++回调函数应用
- ADC驱动
- 【floyd】poj 3615
- Junit基础使用
- 【dp】石子合并问题
- 进程通信
- 几个开发工具的java逆向工程(java reverse engineering)功能比较
- 【floyd】hdu 3665
- 自己编写的linux shell (修改)
- 边界类、控制类、实体类
- 自己编写的linux ls命令
- JVM内存管理:深入Java内存区域与OOM
- Hibernate工作原理及为什么要用?