动态规划学习日记(五)

123
10r(1,2)min{r(1,2)+ r(2,3),r(1,3)}
20r(2,3)
30

例6:租用游艇问题(例)

问题描述: 长江游艇俱乐部在长江上设置了n个游艇出租站1,2,…,n. 游客可在这些游艇出租站租用游艇, 并在下游的任何一个游艇出租站归还游艇. 游艇出租站i到出租站j之间的租金为r(i,j), 1<=i<j<=n. 试设计一个算法, 计算出从游艇出租站1到游艇出租站n所需的最少租金, 并分析算法的计算复杂性.

算法设计: 对于给定的游艇出租站i到游艇出租站j的租金r(i,j), 1<=i<j<=n. 计算出租站1到n所需的最少租金.

数据输入: 第1行有一个正整数n, n<=200, 表示有n个游艇出租站. 接下来n-1行是r(i,j), 1<=i<j<=n.

结果输出: 游艇出租站1到n最少租金.

一、确定状态:

终点:坐标为n;

子问题:设f[i] [j]为从i到j最小得分, f[i] [j] = min{f[i] [k] + f[k+1] [j], r[i] [j]};

二、确定转移方程:

f[i] [j] = min{f[i] [k] + f[k] [j], r[i] [j]};

三、确定初始条件和边界情况:

初始条件:f[1] [1] = 0;

边界情况:f[i] [i+1] = r[i] [i+1];

四、确定计算顺序:

从小到大,填表斜行

代码:

#include <iostream>
#include <cstring>
using namespace std; 
int f[205][205] ;
void Init(){
	memset(f, 0, sizeof(f));
} 
int Min(int x, int y)
{
	return x<y?x:y;
}
void Dp(int n)
{
	int i, j, k, l;
	for(l = 1; l < n; l++)
	{
		for(i = 1; i+l <= n; i++)
		{
			j = i + l;
			for(k = i+1; k < j; k++)
			{
				f[i][j] = Min(f[i][k] + f[k][j], f[i][j]);
			}
		}
	}	
}
int main(int argc, char** argv) {
	Init();
	int n;
	cin>>n;
	int i, j;
	for (i = 1; i <= n - 1; i++)
	{
		for(j = i+1; j <= n; j++)
		{
			cin>>f[i][j];	
		}
	}
	Dp(n);
	cout<<f[1][n]<<endl;	
	return 0;
}

总结
同样是oj上的题,这题挺常规的,就是之前提到的斜填表加最值型问题,因为之前填石子的问题掉坑里还没改好就先发这个了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值