zoukankan      html  css  js  c++  java
  • 38-最短通道

    输出描述

    针对每一个矩阵,找出费用最小的路径,并将其输出。每个矩阵的输出包括两行,第一行是路径本身,即输出每一步所在的行,第二行则是该路径的费用。
    如果对于同一个矩阵有多条不同的费用最小路径,则输出左端行号较小的一条。


    输入样例

    5 6
    3 4 1 2 8 6
    6 1 8 2 7 4
    5 9 3 9 9 5
    8 4 1 3 2 6
    3 7 2 1 2 3


    输出样例

    1 2 1 5 4 5
    11
    */
    //思路: dp吧,需要注意的是它要返回路径,并且返回的是按行排列最小的,这是需要注意的。

    #include <iostream>
    #include <cstring>
    using namespace std;
    long long a[10][102];
    long long dp[10][102];
    int n, m; 
    
    long long fun(int i, int j){  //dp打表 
    	if(dp[i][j])
    		return dp[i][j];
    	if(i >= n || i < 0)
    		return 0;
    	if(j == m - 1)
    		return dp[i][j] = a[i][j]; 
    	if(i > 0 && i < n - 1){
    		dp[i][j] = min(fun(i + 1, j + 1), fun(i, j + 1));
    		return dp[i][j] = min(fun(i - 1, j + 1), dp[i][j]) + a[i][j]; 
    	}
    	if(i == 0){
    		dp[i][j] = min(fun(i + 1, j + 1), fun(i, j + 1));
    		return dp[i][j] = min(fun(n - 1, j + 1), dp[i][j]) + a[i][j];
    	}
    	if(i == n - 1){
    		dp[i][j] = min(fun(i - 1, j + 1), fun(i, j + 1));
    		return dp[i][j] = min(fun(0, j + 1), dp[i][j]) + a[i][j];
    	}
    }
    
    int main(){
    //	int n, m;
    	cin >> n >> m;
    	for(int i = 0; i < n; i++){
    		for(int j = 0; j < m; j++)
    			cin >> a[i][j];
    	}
    
    	long long min = fun(0, 0);
    	int len = 0;
    	for(int i = 1; i < n; i++){  //找到最短路的开始行 
    		if(min > fun(i, 0)){
    			min = fun(i, 0);
    			len = i;	
    		}
    //		cout << fun(i, 0) << endl;
    	}
    	cout << len + 1;
    	for(int i = len, j = 0; j < m - 1; j++){  // 通过已知行推出最短路 
    		int mina = 0, mini = 0;
    //		mina = dp[i][j - 1];
    		if(i > 0 && i < n - 1){				   //由于数组的连续性是圆柱形,故分为四种情况考虑 
    			mini = i - 1;   //要优先选 i - 1;  //保证是按最小行排列的 
    			mina = dp[mini][j + 1];
    			if(dp[i - 1][j + 1] > dp[i][j + 1]){
    				mini = i;
    				mina = dp[i][j + 1];
    			}
    			if(mina > dp[i + 1][j + 1]){
    				mini = i + 1;
    				i++;
    			}
    			else if(mini == i - 1){
    				i--;
    			}
    			cout << " " << mini + 1;
    			continue;
    		}
    		if(i == 0){
    			mini = i; 		//保证是按最小行排列的
    			mina = dp[mini][j + 1];
    			if(dp[i][j + 1] > dp[i + 1][j + 1]){
    				mini = i + 1;
    				mina = dp[i + 1][j + 1];
    			}
    			if(mina > dp[n - 1][j + 1]){
    				mini = n - 1;
    				i = n - 1; 
    			}
    			else if(mini == i){
    				;
    			}
    			else
    				i++;
    			cout << " " << mini + 1;
    			continue;	
    		}
    		if(i == n - 1){
    			mini = 0;   //要优先选坐标小的,故 mini = 0; //保证是按最小行排列的
    			mina = dp[mini][j + 1];
    			if(dp[0][j + 1] > dp[i - 1][j + 1]){
    				mini = i - 1;
    				mina = dp[i - 1][j + 1];
    			}
    			if(mina > dp[i][j + 1]){
    				mini = i;
    			}
    			else if(mini == 0){
    				i = 0;
    			}
    			else
    				i--;
    			cout << " " << mini + 1;
    			continue;
    		}
    	}
    	cout << endl;
    	cout << min;
    	return 0;
    }
    
  • 相关阅读:
    解决ASP.NET中的各种乱码问题
    window.open不被拦截的实现代码
    window.open 浏览器差异.
    使用jQuery获取radio/checkbox组的值的代码收集
    Libnids(Library Network Intrusion Detection System) .
    基于libnids的TCP数据流的还原(多线程实现) .
    Libnids读书笔记 (转)
    PPPOE数据包转换及SharpPcap应用
    [Asp.net]常见word,excel,ppt,pdf在线预览方案,有图有真相,总有一款适合你!
    asp.net 读取word 文档的方法
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/7735061.html
Copyright © 2011-2022 走看看