码迷,mamicode.com
首页 > 其他好文 > 详细

hdu(5402)——Travelling Salesman Problem(模拟题)

时间:2015-08-19 17:04:16      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:模拟题   棋盘染色问题   

啊。。。这道题我一开始的想法是dp,因为我们要求的是在这个区间中和的最大值。

但是没想到只要暴力就好了。

这道题用到了一个著名的想法是:黑白棋盘染色问题。

题意:

现在给你一个n*m的矩阵,然后告诉你每个矩阵中的数字,然后现在要从左上角走到右下角,然后问你所能获得的数字和的最大值是多少。当然,你只能往四个方向走,而且每个点只能走一次。并且叫你输出路径。

思路:

这里我分了三种情况。

1)首先当行或者列数都是1的时候,那么我们就只可能有一种走法(横着走或者是竖着走)然后获取所有的数值。

2)当行数或者是列数其中之一是奇数时,我们肯定能够遍历完这张地图的全部,走法要根据行列奇偶性然后来分情况讨论。

3)这种情况是这道题里面最复杂的一种了。。。我竟然卡了整整一个晚上,我的想法是把每一种情况都分出来,但是实际上不用。

http://blog.csdn.net/queuelovestack/article/details/47756605 (借鉴了这里的思路)

我们只需在白块中找到一个值最小的,然后不走就好了。

那么怎么绕过去呢?想法就是在走到这一行或是那个点的上一行时,用S型的姿势绕过去,相当于这样子是一下子就走了两行,注意一下绕过去之后的L与R的选择就好。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 111
#define inf 99999999
int a[maxn][maxn];
int main(){
	int n,m;
	while(~scanf("%d%d",&n,&m)){
		memset(a,0,sizeof(a));
		int sum=0;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				scanf("%d",&a[i][j]);
				sum+=a[i][j];
			}
		}
		if(n==1){
			printf("%d\n",sum);
			for(int i=1;i<m;i++) printf("R");  puts("");
		}
		else if(m==1){
			printf("%d\n",sum);
			for(int i=1;i<n;i++) printf("D"); puts("");
		}
		else if(n%2||m%2){
			printf("%d\n",sum);
			if(n%2){	//列是偶数; 
				for(int i=1;i<=n;i++){
					for(int j=1;j<m;j++){
						if(i%2){
							printf("R");
						}
						else printf("L");
					}
					if(i!=n) printf("D");
				}
			}
			else{		//行是偶数; 
				for(int i=1;i<=m;i++){
					for(int j=1;j<n;j++){
						if(i%2){
						    printf("D");
						}
						else printf("U");
					}
					if(i!=m) printf("R");
				}
			}
		}
		//以上都是对的! 
		else{
			int tx=0,ty=0;
			int ans=inf;
			//下面的目的是为了找到在白块中数值最小的那个点的坐标; 
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(i%2){
						if(j%2==0){
							if(ans>a[i][j]){
								ans=a[i][j];
								tx=i; ty=j;
							}
						}
					}
					else if(i%2==0){
						if(j%2){
							if(ans>a[i][j]){
								ans=a[i][j];
								tx=i; ty=j;
							}
						}
					}
				}
			}
			printf("%d\n",sum-ans);
			//printf("%d %d\n",tx,ty);
			for(int i=1;i<=n;i+=2){
				if(i==tx||i+1==tx){
					for(int j=1;j<ty;j++){
						if(j&1) printf("D");
						else printf("U");
						printf("R");
					}
					if(ty<m) printf("R");
					for(int j=ty+1;j<=m;j++){
						if(j&1) printf("U");
						else printf("D");
						if(j<m) printf("R");
					}
					if(tx<n-1) printf("D");
				}
				else if(tx<i){
					for(int j=1;j<m;j++){
						printf("L");
					}
					printf("D");
					for(int j=1;j<m;j++){
						printf("R");
					}
					if(i<n-1) printf("D");
				}
				else{
					for(int j=1;j<m;j++){
						printf("R");
					}
					printf("D");
					for(int j=1;j<m;j++){
						printf("L");
					}
					printf("D");
				}
			}
		}
		printf("\n");
	}
}

orz多校。。。

版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu(5402)——Travelling Salesman Problem(模拟题)

标签:模拟题   棋盘染色问题   

原文地址:http://blog.csdn.net/acmer_hades/article/details/47779929

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!