第三章笔记

设置m[i][j] 表示从第i个到第j个数的最小代价值,当j - i = 1(只有两个数),直接返回a[i] + a[j]。若j大于i的时候,可以随机添加括号,通过比较留下最小值。

状态方程:      m[i][j] =min(dp(i,j),(dp(i,k) + dp(k+1,j) + s[j-1] - s[i-1] );

                                                                       (i<=k<j)(s[0] == 0)//k为随机添加的括号     

边界条件:      m[i][j] = 0 ;(j == i) m[i][j] = a[i]+[j] ;( i =j+1)

空间复杂度为O(n^2),时间复杂度为O(n^3)don

动态规划将复杂的问题分解成更小的子问题,有助于理解和解决复杂问题,一般用来解决最优化问题,并且通过存储中间结果,提高效率。

#include<iostream>
#include<cstring>
using namespace std;
int n;//石头的个数
int a[108];//石头的质量 
int m[108][108] = {-1};//m[i][j]表示 第i个石头到第j个石头的总代价。
int sum[108];//表示从第一个石头到第j个石头的总质量 
//m[i][j] = m[i][k] + m[k+1][j] + sum[j] - sum[i-1]从第j到第i个石头的总质量 (包括第i个石头)
//m[i][j] = 0 如果i=j则没有代价 

int check(int i, int j)
{   
    int min = 1000000;
	if(m[i][j] != -1)
	{
		return m[i][j];
	}
	if(i == j)
	{
		m[i][j] = 0;
		return m[i][j];
	}
	if(i+1 == j)
	  {
	  	m[i][j] = a[i] + a[j];
	  	return m[i][j];	
	  }
	else
	{
		for(int k=i+1; k < j; k++)
	    {
		   int cal = check(i, k) + check(k+1, j) + sum[j] - sum[i-1];
		   if(cal < min)
		    min = cal;
	    } 
	    m[i][j] = min;
	    return m[i][j];
	}
} 
int main()
{
	cin >> n;
	sum[0] = 0;
	memset(m,-1,sizeof(m));
	for(int i=1; i <= n; i++)
	{
		cin >> a[i];
		sum[i] = sum[i-1] + a[i]; 
		//cout << sum[i] << endl;//根据这里我们可以得到sum[0]需要等于零,在前面补充 
	} 
	cout << check(1,n);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值