算法之租用游艇问题
2016-10-28 10:33
1036 查看
一、问题描述:
长江游艇俱乐部在长江上设置了n个游艇出租站1,2,3…,n。游客可以在这些游艇出租站用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i<j=n。试设计一个算法,计算从游艇出租站1到出租站n所需的最少租金。二、算法设计:
对于给定的游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i<j<=n,计算从游艇出租站1到游艇出租站n所需的最少租金。三、数据输入:
由文件input.txt提供输入数据。文件的第1行中有1个正整数n(n<=200),表示有n个游艇出租站,接下来的n-1行是r(i,j),1<=i<j=n.四、结果输出:
将计算出的从游艇出租站1到游艇出租站n所需要的最少租金输出到文件output.txt。输入文件示例 输出文件示例
3 12
5 15
7
五、代码实现:
#include<iostream> #include<fstream> using namespace std; /* 基本思想:求解所有可选择的通路中花费最小的组合方式,可以把每种通向终点的可能都计算出来,然后取最小值; author@:token_gpl */ const int M = 200; //最多有200个出租站 int rent[200][200]; //用于存放租金 int rentQes(int n){ int i, j, k; //定义三个索引 int mark = n - 1; //定义一个标记 j = n; //j为最后的一个租店点索引 for (i = n - 2; i >= 1; i--){ //从倒数第二行开始往前遍历 for (k = mark; k <= n - 1; k++){ //k控制该行的列和下一行的行索引 if (rent[i][j]>(rent[i][k] + rent[k][j])){ //用每一行最后一个数 与 其他方案加起来得到的数比较 ;比如,rent[3][5]和rent[3][4]+rent[4][5]比较,因为rent[4][5]+rent[3][4]效果=rent[3][5] rent[i][j] = rent[i][k] + rent[k][j]; } else{ rent[i][j] = rent[i][j]; } } mark--; //索引每次都减小一个 } return rent[1] ; //最后右上角的值就是我们所需要的最小值 } int main(){ ifstream in; //文件输入流 ofstream out; //文件输出流 in.open("input.txt"); out.open("output.txt"); int n; in >> n; int j, k = 2; for (int i = 1; i <= n - 1; i++){ for (j = k; j <= n; j++){ //此处的下标做了特殊处理,使用的是i,j形式, in >> rent[i][j]; // 比如 12 13 14 【15】 }k++; // 23 24 【25】 } // 34 【35】 这种格式,比较好处理 out << rentQes(n) << endl; // 【45】 return 0; }
六、总结与分析:
☆采用动态规划的思想,从下到上的方向每次将能够直接达到终点的情况数据计算出来,并且互相比较将最小值保存到该行的最后一个元素值,依次做这样子的处理,则最后的最优值保存在第一行的最后一个元素位置上。☆此算法巧妙的设置了下标值,以租站位置作为下标值,比如出租站1--出租站3则下标设置为rent[1][3],以此种方法,使得问题的处理和理解上更加的简便。
☆文件输入输出流的形式给程序传入参数,我们这里采用非常之简单的文件输入输出流来操作,引入#include<fstream>其中包含了ifstream(用来从文件读取参数到程序)和ofstream(用来从程序输出参数到文件),具体使用情况参考程序源代码即可。