第九章例题 D- Unidirectional TSP

/*SE:wn------王宁*/

这是一道简单的多阶段决策题目,但是要注意细节处理。

#include<bits/stdc++.h>
using namespace std;
const int maxr=15;
const int maxc=105;
int mat[maxr][maxc];
int d[maxr][maxc];
int path[maxc];
int main()
{
	int m,n,i,j,ans,p,t;
	while(~scanf("%d%d",&m,&n))
	{
		for(i=0;i<m;i++)
			for(j=0;j<n;j++) scanf("%d",&mat[i][j]);
		/*我也是用逆推的,不过并没有用next记录下一个位置
		而是采用相邻位置dp值的差值是否等于前一个元素
		并用临时变量来确定最小字典序*/
		for(j=m-1;j>=0;j--) d[j][n-1]=mat[j][n-1];
		for(i=n-2;i>=0;i--)
			for(j=0;j<m;j++)
			{
				d[j][i]=min(mat[j][i]+d[j][i+1],mat[j][i]+d[(j-1+m)%m][i+1]);
				d[j][i]=min(d[j][i],mat[j][i]+d[(j+1+m)%m][i+1]);
			}
		ans=d[0][0],p=0;
		for(i=1;i<m;i++) if(d[i][0]<ans){ ans=d[i][0]; p=i; }
		for(i=0;i<m;i++) if(d[i][0]==ans) { p=i; break; }
		printf("%d",p+1);
		for(i=1;i<n;i++)
		{
			/*t一开始如果没有赋值,初值是0,而如果没有正确的在第一次比较中
			就将t改变过来,那么后面即使找到对的路径也不能比t(t=0)小了,
			之后就会出现连续的错误
			所以为了每次使用都能到达既能走通,又是字典序最小的状况
			t作为记录位置的参数应该设置的很大——肯定有值能将它改变但是也要让人家
			达到你的门槛*/
			t=10000000;
			if(d[(p-1+m)%m][i]==d[p][i-1]-mat[p][i-1]) { t=(p-1+m)%m; }
			if((d[(p)%m][i]==d[p][i-1]-mat[p][i-1])&&p<t) { t=p;  }
			if((d[(p+1+m)%m][i]==d[p][i-1]-mat[p][i-1])&&(p+1+m)%m<t) { t=(p+1+m)%m;  }
			p=t;
			printf(" %d",t+1); 
		}
		printf("\n%d\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/JXUFE_ACMer/article/details/81476511