石子归并 3
来源:互联网 发布:vb 打开网页 编辑:程序博客网 时间:2024/05/18 22:09
题目描述 Description
有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1]。问安排怎样的合并顺序,能够使得总合并代价达到最小。
输入描述 Input Description
第一行一个整数n(n<=3000)
第二行n个整数w1,w2…wn (wi <= 3000)
输出描述 Output Description
一个整数表示最小合并代价
样例输入 Sample Input
4
4 1 1 4
样例输出 Sample Output
18
数据范围及提示 Data Size & Hint
数据范围相比“石子归并” 扩大了
我有话说:
这道题明确的说明了数据范围的增大,所以用O(n^3)的算法是没有办法通过的,5000ms左右吧。所以要进行优化。方法是平行四边形优化。
关于平行四边形优化,引用网上的部分资料:
因为在动态规划中,有这样的一类问题
状态转移方程 dp[i][j]=min{dp[i][k-1]+dp[k][j]}+w[i][j] k>i&&k<=j 时间复杂度为 O(n*n*n)
且有如下一些定义和定理:
如果一个函数w[i][j],满足 w[i][j]+w[i’][j’]<=w[i][j’]+w[i’][j] i<=i’<=j<=j’ 则称w满足凸四边形不等式
如果一个函数w[i][j],满足 w[i’][j]<=w[i][j’] i<=i’<=j<=j’ 则称w关于区间包含关系单调
定理1:如果w同时满足四边形不等式和区间单调关系,则dp也满足四边形不等式
定理2:如果定理1条件满足时让dp[i][j]取最小值的k为K[i][j],则K[i][j-1]<=K[i][j]<=K[i+1][j]
注:定理2是四边形不等式优化的关键所在,它说明了决策具有单调性,然后我们可以据此来缩小决策枚举的区间,进行优化
定理3:w为凸当且仅当 w[i][j]+w[i+1][j+1]<=w[i+1][j]+w[i][j+1]
几点说明:
1:定理1的证明比较烦躁,详细的可以见《动态规划算法的优化技巧》毛子青 大神的论文
2:定理3其实告诉我们验证w是否为凸的方法,就是固定一个变量,然后看成是一个一元函数,进而判断单调性。
如,我们可以固定j算出w[i][j+1]-w[i][j]关于i的表达式,看它是关于i递增还是递减,如果是递减,则w为凸
3:实际操作中,我们往往并不需要进行烦躁的证明,而只需要打表,然后观察就行了
如w[i][j],dp[i][j]是否满足四边形不等式啊,w[i][j]是否单调啊,决策函数K[i][j]是否满足定理2的不等式关系啊,都可以通过打表来搞
=====================分割线=====================
最有代价用d[i,j]表示
d[i,j]=min{d[i,k-1]+d[k+1,j]}+w[i,j]
其中w[i,j]=sum[i,j]
四边形不等式
w[a,c]+w[b,d]<=w[b,c]+wa,d 就称其满足凸四边形不等式
决策单调性
w[i,j]<=w[i’,j’] ([i,j]属于[i’,j’]) 既 i’<=i
#include <cstdio>#include <cstring>#include <algorithm>#define N 3100int dp[N][N],sum[N],s[N][N];int main(){ int n; scanf("%d",&n); int a[N];sum[0]=0; memset(s,0,sizeof(s)); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); s[i][i]=i; sum[i]=sum[i-1]+a[i]; } memset(dp,0,sizeof(dp)); int i,j,l,k; for(l = 2; l <= n; ++l) { for(i = 1; i <= n - l + 1; ++i) { j = i + l - 1; dp[i][j] = 2100000000; for(k = s[i][j-1]; k <= s[i+1][j]; ++k) { if(dp[i][j]>dp[i][k] + dp[k + 1][j] + sum[j] - sum[i-1]) { dp[i][j]=dp[i][k] + dp[k + 1][j] + sum[j] - sum[i-1]; s[i][j]=k;//个人理解就是把合并成的石子堆最小代价给记录下来。不知大神们是否认同。 } } } } printf("%d\n", dp[1][n]); return 0;}
- 石子归并 3
- codevs3002 石子归并3
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并问题
- mac 安装 gdb
- leetcode:Maximal Rectangle
- hhuc-acm训练深搜b
- 获取客户端ip的方式(适用于公网与局域网)
- ADB server didn't ACK 解决办法
- 石子归并 3
- STS初始化环境搭建
- android布局优化
- NYOJ239月老的难题(二分图的最大匹配模版)
- gcd求最大公约数
- Tomcat 安装和配置
- C#进程间通信--API传递参数(SendMessage)
- hadoop支持SnappyCodec的步骤
- PHPExcel(2)-- 导入功能