UVa 116

水题,简单的DAG的扩展,关于矩阵是循环的,利用模运算解决就好,字典序就单独开一个数组来记录

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;

const int maxm= 15;
const int maxn= 105;
const int INF= 0x3f3f3f3f;

int M[maxm][maxn], nxt[maxm][maxn], dp[maxm][maxn];

int main()
{
	int m, n; 

	while (2== scanf("%d %d", &m, &n)){
		for (int i= 0; i< m; ++i){
			for (int j= 1; j<= n; ++j){
				scanf("%d", &M[i][j]);
			}
		}
		// dp[i][j]= min(u, d, r)+M[i][j]
		// u= dp[(i+m-1)%m][j+1]
		// d= dp[(i+m+1)%m][j+1]
		int ans= INF;
		int s= -1;
		for (int j= n; j> 0; --j){
			for (int i= 0; i< m; ++i){
				if (n== j){
					dp[i][j]= M[i][j];
				}
				else{
					int o[3]= {(i+m-1)%m, i, (i+m+1)%m};
					int x= INF;
					for (int k= 0; k< 3; ++k){
						if (dp[o[k]][j+1]< x){
							x= dp[o[k]][j+1];
							nxt[i][j]= o[k];
						}
						else if(dp[o[k]][j+1]== x){
							nxt[i][j]= min(o[k], nxt[i][j]);
						}
					}
					dp[i][j]= x+M[i][j];
				}
				if (j== 1 && dp[i][j]< ans){
					ans= dp[i][j];
					s= i;
				}
			}
		}

		printf("%d", s+1);
		for (int i= nxt[s][1], j= 2; j<= n; i= nxt[i][j++]){
			printf(" %d", i+1);
		}
		printf("\n%d\n", dp[s][1]);
	}
}
posted @ 2020-09-30 16:22  IdiotNe  阅读(72)  评论(0编辑  收藏  举报