游船费问题——动态规划

咳咳 以下均为原创,发散乱想

好吧,一张图片说明完毕,我们用路径长短表示坐船费用,求最少费用:

ps:本题属于最短路线求解。发散:可以将路径长短通过 线性映射或 非线性映射转化为某种(加权)量,来求解最优(加权)问题。ok,这就看你的脑容量有多大了!

分析:1.话说动态规划两要素:下一阶段的最优状态=现阶段最优状态+当前决策 (这是从自底向上的角度出发思考的,对应着最优递归关系式)

2.需要个关键技巧:合适的定义一种最优状态表来记录最优状态值,本题我们用m[i][j]表示i站到j站的最少费用,m[i][j]就是我们要找的最优状态表(本题中它属于二维表)

3.必须利用题目信息,该信息是决策用到的依据。本文用p[i][j]表示i站直接到j站的费用,i的取值范围(0,n-1),j的取值范围(1,n)。

仔细分析最优子结构,根据问题内容科学写出最优递归关系式。

代码:

 1 //
 2 //
 3
 4 #include "stdafx.h"
 5 #include <iostream>
 6 using namespace std;
 7
 8 class mincost_chuanfei {
 9 public:
10     int n;
11     int **p, **m,**t;
12
13     void data_read()
14     {
15         int i, j;
16         cin >> n;
17         p = new int*[n];
18         for (i = 0; i < n; i++) p[i] = new int[n+1];//p[i][j]表示i站直接到j站的费用,[email protected](0,n-1),[email protected](1,n)
19         m = new int*[n];
20         for (i = 0; i < n; i++) m[i] = new int[n+1];//m[i][j]表示i站到j站的最少费用
21         t = new int*[n];
22         for (i = 0; i < n; i++) t[i] = new int[n+1];//t[i][j]用于跟踪i站到j站之间断开的某一站序号,用于构造最优解
23         for (i = 0; i < n; i++)
24         {
25             for (j = i + 1; j <= n; j++) cin >> p[i][j];
26         }
27     }
28
29     void data_processing()
30     {
31         int i, j, s,tmp;
32         for (s = 1; s<=n; s++)//让步距s从1加大到n
33         {
34             for (i = 0; i<=n - s; i++)//[email protected](0,n-s)
35             {
36                 j = s + i;//j等于i+步距s
37                 if (s == 1) { m[i][j] = p[i][j]; t[i][j] = j; }
38                 else {
39                     tmp = p[i][j]; t[i][j] = j;
40                     for (int k = i + 1; k < j; k++)
41                     {
42                         if (m[i][k] + m[k][j] < tmp) { tmp = m[i][k] + m[k][j]; t[i][j]=k;}
43                     }
44                     m[i][j] = tmp;
45
46                      }
47             }
48         }
49
50     }
51
52     void Traceback(int i, int j, int** t)
53     {
54         if (t[i][j] == j) {
55             cout << "start:"<<i<<"      end:"<<j << endl; return;
56         }
57         Traceback(i, t[i][j], t);
58         Traceback(t[i][j], j, t);
59     }
60
61
62
63     void data_output()
64     {
65         cout << "the min cost:" << m[0][n] << endl;
66         Traceback(0, n, t);
67
68     }
69 };
70
71
72
73
74 int main()
75 {
76     mincost_chuanfei dd;
77     dd.data_read();
78     dd.data_processing();
79     dd.data_output();
80
81
82     return 0;
83 }

                 

时间: 2024-10-06 04:46:00

游船费问题——动态规划的相关文章

游船费问题

问题描述 某旅游城市在长江边开辟了若干个旅游景点.一个游船俱乐部在这些景点都设置了游艇出租站.游客可在这些游船出租站租用游船,并在下游的任何一个游船出租站归还游船,从一个游船出租站到下游的游船出租站间的租金明码标价.你的任务是为游客计算从起点到终点站间的最小租船费用. 输入 输入文件有若干组数据,每组测试数据的第一行上有一个整数n(1<=n<=100),表示上游的起点站0到下游有n个游船出租站 1,2,...,n.接下来有n行,这n行中的第1行有n个整数,分别表示第0站到第1,2,3,...,

动态规划(dp)专题

航线设置   问题描述在美丽的莱茵河畔,每边都分布着N个城市,两边的城市都是唯一对应的友好城市,现需要在友好城市间开通航线以加强往来,但因为莱茵河常年大雾,如果开设的航线发生交叉就有可能出现碰船的现象.现在要求尽可能多地开通航线并且使航线不能相交.输入有若干组测试数据,每组测试数据的第一行是一个整数n,它表示每边都分布着n个城市(1<=n<=1000).接着有n行,每一行有2个整数s,t,之间有一个空格,s表示起点城市,t表示终点城市.输出对每组测试数据,首先在一行上输出"Case

动态规划学习中的一道题目

记得初中时候的一篇文章说,做学问,必须要有学和问两个方面. 做了一些动态规划题目之后偶然看到这个介绍动态规划的文章.然后遇见第一道题目就卡壳. 经过反思文章以及自己思考,总算对题目有了一些理解.下面分享给大家,初学者们看到这个题目不至于太过茫然——像我一样. 工厂生产某种产品,每单位(千件)的成本为1(千元),每次开工的固定成本为3(千元),工厂每季度的最大生产能力为6(千件).经调查,市场对该产品的需求量第一.二.三.四季度分别为        2,3,2,4(千件).如果工厂在第一.二季度将

算法总结1——动态规划

该文章所用的图片取自上海交大电院高晓沨老师上课所用的课件~顺便说一句,高老师的英语简直太棒了! 网址:http://cs.sjtu.edu.cn/~gao-xf/algorithm/ 正值期中,即将考试,总结一下之前学的算法还是很有必要的,一方面记录以备之后用到,一方面防止自己在复习的过程中走神...之前做笔记总是想着自己看懂就好,其实很多地方没有写明白,导致之后看起来还是比较费力的,而目前任务多又重(估计之后也好不到哪里去),只想能不动脑就不动脑啊.所以想让自己写出的东西通俗易懂,以后只管端起

Leetcode 494 Target Sum 动态规划 背包+滚动数据

这是一道水题,作为没有货的水货楼主如是说. 题意:已知一个数组nums {a1,a2,a3,.....,an}(其中0<ai <=1000(1<=k<=n, n<=20))和一个数S c1a1c2a2c3a3......cnan = S, 其中ci(1<=i<=n)可以在加号和减号之中任选. 求有多少种{c1,c2,c3,...,cn}的排列能使上述等式成立. 例如: 输入:nums is [1, 1, 1, 1, 1], S is 3. 输出 : 5符合要求5种

活动选择的贪心算法与动态规划(未完成)

// greedy_algorithm.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include<queue> using namespace std; #define NofActivity 11 int c[NofActivity + 1][NofActivity + 1]; int reme[NofActivity + 1][NofActivity + 1]; //活动的

求不相邻金币相加和的最大值--动态规划1

求不相邻金币相加和的最大值. 输入n个金币的金币面值(正数自定义),求这些金币不相邻和的最大值. 动态规划问题1 设f(n)为第n个金币数的最大值,f(0)=0,f(1)=a[1],输入的数组从下标为1开始. f(n)=max{a[n]+f(n-2),f(n-1)}. 代码如下: import java.util.Scanner; public class Jin_bi_zui_da_zhi { public static void main(String[] args) { Scanner s

[动态规划] 黑客的攻击 Hacker&#39;s CrackDown Uva 11825

抽象为数学模型就是,  取尽可能多的互不相交的子集 ,  使得每一个子集都能覆盖全集 #include <algorithm> #include <cstring> #include <cstdio> using namespace std; int n; int P[1000],cover[1000],f[1000]; int main(){ scanf("%d", &n); for (int i = 0; i < n;i++) {

Beauty Of algorithms(七)动态规划 钢条分割 矩阵链乘 最长公共子序列 最优二叉树

1.动态规划                动态规划的方法与方法类似,英文"dynamic programming",这里的programming不是程序的意思,而是一种表格法.都是通过组合子问题的解来解决原问题,分治方法将划分为互不相交的子问题,递归的求解子问题,再将它们的解组合起来求出原问题的解.与之相反动态规划应用于子问题的重叠情况,即不同的子问题具有公共的子问题,子问题的求解是递归进行 的,将其划分为更小的子问题,动态规划,每个子问题只求解一次,将其保存在表格中,从而无需每次求