zjnu1181 石子合并【基础算法・动态规划】——高级
来源:互联网 发布:游戏代练app源码 编辑:程序博客网 时间:2024/06/11 17:04
Description
在操场上沿一直线排列着
n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的两堆石子合并成新的一堆,
并将新的一堆石子数记为该次合并的得分。允许在第一次合并前对调一次相邻两堆石子的次序。
计算在上述条件下将n堆石子合并成一堆的最小得分。
n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的两堆石子合并成新的一堆,
并将新的一堆石子数记为该次合并的得分。允许在第一次合并前对调一次相邻两堆石子的次序。
计算在上述条件下将n堆石子合并成一堆的最小得分。
Input
输入数据共有二行,其中,第1行是石子堆数n≤100;
第2行是顺序排列的各堆石子数(≤20),每两个数之间用空格分隔。
第2行是顺序排列的各堆石子数(≤20),每两个数之间用空格分隔。
Output
输出合并的最小得分。
Sample Input
32 5 1
Sample Output
11
第一道区间dp,这题设一个数组dp[i][j]表示从i取到j的最小得分。
状态转移方程:用len表示所选数字的个数,dp[i][i+len-1]=min(dp[i][i+len-1],dp[i][k]+dp[k+1][i+len-1]+sum[i+len-1]-sum[i-1]);这里注意所有的dp[i][i]为0,因为只有一个数的时候不用合并,所以是0。因为题目允许第一次开始取的时候相邻数字能搞交换,所以外面加个循环,同时每次的sum[]都要重新初始化。另外,这题用四边形优化会大大加快速度。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<string>#include<algorithm>using namespace std;#define inf 99999999#define ll long longint sum[200],a[200];int dp[200][200];int main(){ int n,m,i,j,c,len,k,t; int minx; while(scanf("%d",&n)!=EOF) { sum[0]=0; for(i=1;i<=n;i++){ scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i]; dp[i][i]=0; } minx=inf; for(t=1;t<=n-1;t++){ sum[t]=sum[t]-a[t]+a[t+1]; for(len=2;len<=n;len++){ for(i=1;i<=n-len+1;i++){ dp[i][i+len-1 ]=inf; for(k=i;k<=i+len-2;k++){ dp[i][i+len-1]=min(dp[i][i+len-1],dp[i][k]+dp[k+1][i+len-1]+sum[i+len-1]-sum[i-1]); } } } sum[t]=sum[t]+a[t]-a[t+1]; minx=min(minx,dp[1][n]); } printf("%d\n",minx); } return 0;}
四边形优化:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<string>#include<algorithm>using namespace std;#define inf 99999999#define ll long longint sum[200],a[200],s[200][200];/*s[i][j]函数表示区间[i,j]从k点分开是最优的*/int dp[200][200];int main(){ int n,m,i,j,c,len,k,t; int minx; while(scanf("%d",&n)!=EOF) { sum[0]=0; for(i=1;i<=n;i++){ scanf("%d",&a[i]); s[i][i]=i; sum[i]=sum[i-1]+a[i]; dp[i][i]=0; } minx=inf; for(t=1;t<=n-1;t++){ sum[t]=sum[t]-a[t]+a[t+1]; for(len=2;len<=n;len++){ for(i=1;i<=n-len+1;i++){ j=i+len-1; dp[i][j]=inf; 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; } } } } sum[t]=sum[t]+a[t]-a[t+1]; minx=min(minx,dp[1][n]); } printf("%d\n",minx); } return 0;}
0 0
- zjnu1181 石子合并【基础算法・动态规划】——高级
- 石子合并——动态规划
- 动态规划——石子合并
- 深入理解合并类动态规划——合并石子
- 动态规划-合并石子
- [动态规划] 石子合并
- 动态规划——洛谷1880石子合并
- 动态规划之石子合并
- 动态规划:石子合并问题
- 动态规划之石子合并
- 动态规划之石子合并
- 动态规划石子合并问题
- 算法_动态规划_石子合并问题
- zjnu(1183)——括号序列【基础算法・动态规划】——高级
- 动态规划(合并类)--石子合并
- 合并类动态规划,石子归并,合并石子解题报告
- 动态规划入门 合并石子 COGS1660 石子合并
- 石子合并问题 --动态规划--解法1
- 多态
- [一]三种 hls 解析源码 vlc ffmpeg exoplayer
- linux系统编程:进程间通信-mmap
- 第二周编程作业 信号报告
- 关于卷积---各行各业从业者的理解
- zjnu1181 石子合并【基础算法・动态规划】——高级
- [二]三种 hls 解析源码 vlc ffmpeg exoplayer
- 三分钟看懂Snmp协议分析
- [LeetCode][Java] Merge Intervals
- Codeforces Round #312 (Div. 2) 完整题解
- WebService大讲堂之Axis2(1):用POJO实现0配置的WebService
- JAVA基础(2)——分支和循环结构
- 正则表达式,一些例子
- 9.Laravel5学习笔记:在laravel中注册自己的服务到容器中