合并石子(求最小代价)
来源:互联网 发布:kbengine java 编辑:程序博客网 时间:2024/05/22 03:23
题目描述:
设有N堆沙子排成一排,其编号为1,2,3,…,N(N<=100)。每堆沙子有一定的数量。现要将N堆沙子并成为一堆。归并的过程只能每次将相邻的两堆沙子堆成一堆,这样经过N-1次归并后成为一堆。总的代价最小为多少。
分析
令f[i,j]表示归并第i个数到第j数的最小代价,sum[i,j]表示第i个数到第j个数的和,这个可以事先计算出来。sum[i,j]可以在O(1)的时间内算出.
容易的到以下的动态转移方程:
f[i,j]=min(f[i,k]+f[k+1,j]+sum[i,j])
阶段:以归并石子的长度为阶段,一共有n-1个阶段。
状态:每个阶段有多少堆石子要归并,当归并长度为2时,有n-1个状态;
当归并长度为3时,有n-2个状态;
当归并长度为n时,有1个状态。
决策:当归并长度为2时,有1个决策;当归并长度为3时,有2个决策;
当归并长度为n时,有n-1个决策。
#include <stdio.h>#include<string.h>int DP[110][110];//记录状态int A[110];//石子重量int S[110];//S[i]代表石子1到j的重量总和int n;int dp(int i,int j)//代表石子i到j的最小耗费{ if(DP[i][j]!=-1) return DP[i][j]; if(i==j) { DP[i][j]=0; return 0; } int ans=9999999; int k; for(k=i;k<j;k++) { int temp=dp(i,k)+dp(k+1,j)+S[k]-S[i]+A[i]+S[j]-S[k+1]+A[k+1];//合并石子的耗费 if(temp<ans) ans=temp; } DP[i][j]=ans; return ans;}int main(){ scanf("%d",&n); memset(DP,-1,sizeof(DP)); int i; for(i=1;i<=n;i++) scanf("%d",&A[i]); int s=0; for(i=1;i<=n;i++) { s+=A[i]; S[i]=s; //便于以后计算i到j石子的和 } printf("%d\n",dp(1,n)); return 0;}这道题由于没有足够的测试数据来验证,总是感觉哪里不太对。
阅读全文
0 0
- 合并石子(求最小代价)
- 区间DP-合并石子(求最小/最代价 )
- 求数列合并最小代价
- 【贪心法反例】最小代价数组合并
- 【求最小代价环floyd】POJ 1734
- 石子合并(一)
- 石子合并(一)
- 石子合并(一)
- 石子合并(一)
- 石子合并(一)
- 石子合并(一)
- 石子合并(NOI1995)
- 石子合并(NOI1995)
- 石子合并(一)
- 石子合并(一)
- 石子合并(一)
- 最小(代价)生成树
- hdu 4738 Caocao's Bridges 【求最小代价的割边(桥)】
- 取整函数的性质
- Python学习(十八)——list tuple namedtuple
- 对象的notify方法的含义和对象锁释放的三种情况
- Tomcat部署web项目,如何直接通过域名访问,不加项目名称
- Python 直接赋值、浅拷贝和深度拷贝解析
- 合并石子(求最小代价)
- JavaIOUtils
- msgbuf实现mtext[1]可变长代码
- 十进制转二进制
- 自定义开源控件的绘制实例-——价格区间图
- MVC中创建的数据库实体获取数据的基本语法
- lambda表达式-java中的应用
- form表单
- idea安装阿里巴巴java规范插件的两种方式