NYOJ 737 石子合并(一)(区间DP、平行四边形优化、GarsiaWachs算法)
来源:互联网 发布:林珊珊几个淘宝店铺 编辑:程序博客网 时间:2024/05/29 21:33
石子合并(一)
时间限制:1000 ms | 内存限制:65535 KB
难度:3
- 描述
- 有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。
- 输入
- 有多组测试数据,输入到文件结束。
每组测试数据第一行有一个整数n,表示有n堆石子。
接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开 - 输出
- 输出总代价的最小值,占单独的一行
- 样例输入
31 2 3713 7 8 16 21 4 18
- 样例输出
9239
三种方法,对应时间效率分别为O(n^3)、O(n^2)、O(nlogn)
普通的区间DP,很容易想到,时间效率为O(n^3)
//O(n^3)#include <stdio.h>int dp[203][203],sum[203];int min(int a,int b){return a>b?b:a;}int main(){int n,a;while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++){scanf("%d",&a);sum[i]=sum[i-1]+a;dp[i][i]=0;}// 区间DPfor(int count=2;count<=n;count++){ // 遍历合并count=2堆、3堆、...n堆的情况for(int start=1;start<=n-count+1;start++){ // start表示每个区间的始点int end=start+count-1; // end表示对应的该区间的终点dp[start][end]=0x3f3f3f3f;for(int mid=start;mid<=end;mid++){dp[start][end]=min(dp[start][end],dp[start][mid]+dp[mid+1][end]+sum[end]-sum[start-1]);}}}printf("%d\n",dp[1][n]);}return 0;}
平行四边形优化后时间效率为O(n^2)
附四边形优化讲解:http://www.cnblogs.com/zxndgv/archive/2011/08/02/2125242.html
//O(n^2)#include <stdio.h>#include <string.h>int dp[203][203], sum[203], s[203][203];int main(){int n, i, j, k, len, x;while(scanf("%d",&n)!=EOF){sum[0]=0;for(i=1;i<=n;i++){scanf("%d",&x);sum[i]=sum[i-1]+x;dp[i][i]=0;s[i][i]=i;}for(len=2;len<=n;len++){for(i=1;i<=n-len+1;i++){j=i+len-1;dp[i][j] = 0x3f3f3f3f;for(k=s[i][j-1];k<=s[i+1][j];k++){if(dp[i][j]>dp[i][k-1]+dp[k][j]+sum[j]-sum[i-1]){dp[i][j]=dp[i][k-1]+dp[k][j]+sum[j]-sum[i-1];s[i][j]=k;}}}}printf("%d\n",dp[1][n]);}return 0;}
石子合并的GarsiaWachs算法,时间效率可达O(nlogn)
附石子合并的GarsiaWachs算法讲解:http://blog.csdn.net/acdreamers/article/details/18043897
//O(nlogn)#include <cstdio>const int N=210;int n,t,stone[N],ans;void combine(int k){ int tmp=stone[k]+stone[k-1]; ans+=tmp; for(int i=k; i<t-1; i++) stone[i]=stone[i+1]; t--; int j; for(j=k-1; j>0 && stone[j-1]<tmp; j--) stone[j] = stone[j-1]; stone[j] = tmp; while(j >= 2 && stone[j] >= stone[j-2]) { int d = t - j; combine(j-1); j = t-d; }}int main(){ while(~scanf("%d",&n)) { for(int i=0; i<n; i++) scanf("%d",&stone[i]); t=1,ans=0; for(int i=1;i<n;i++) { stone[t++]=stone[i]; while(t >=3 && stone[t-3]<=stone[t-1]) combine(t-2); } while(t > 1) combine(t-1); printf("%d\n" , ans); } return 0;}
0 0
- NYOJ 737 石子合并(一)(区间DP、平行四边形优化、GarsiaWachs算法)
- NYOJ 737 石子合并(一) (区间DP+平行四边形优化)
- 蓝桥杯/nyoj 737 合并石子 区间dp+平行四边形优化
- NYOJ 石子合并(一)(区间DP)
- NYOJ题目737石子合并(一)(区间dp)
- NYOJ 737 石子合并(一)(区间dp)
- nyoj 737 石子合并(一)(区间dp)
- nyoj 737 石子合并(一)(区间DP)
- NYOJ 737 — 石子合并(一) 区间dp
- nyoj 737 石子合并(一) 【区间dp】
- nyoj 737 石子合并(一) 区间dp
- NYOJ 737 石子合并(一)(区间dp)
- Nyoj 737: 石子合并(一)(区间DP+四边形优化)
- bzoj3229 [Sdoi2008]石子合并(非dp的GarsiaWachs算法)
- 石子合并问题 (朴素区间DP&&GarsiaWachs算法)
- NYOJ 石子合并(一)(区间dp)
- NYOJ 石子合并(一)经典区间DP
- nyoj 737 合并石子一(dp)
- Ibaits调用存储过程
- C/C++总结
- 关于微信微信 onresp 收不到返回的结果
- 运行java时出现 “could not open jvm.cfg ”的解决办法之一
- Hibernate 5.1概述
- NYOJ 737 石子合并(一)(区间DP、平行四边形优化、GarsiaWachs算法)
- hdu1080 Human Gene Functions()
- Codeforces 149D Coloring Brackets (不错的区间DP)
- Java1.8源码集合类学习UML图——Collection接口&AbstractCollection抽象类
- 如何学习struts框架?
- Android获取屏幕高度、状态栏高度、标题栏高度
- 混合加密算法(RSA 和DES)
- 获取控件的宽高和设置控件的宽高
- Android GridView属性集合