poj 2353

题目的大意就是给了M*N的矩阵,求一条从第一行到最后一行的路径(只能从上往下走),使得路径上的数字总和最小,输出该路径,如有多条,则任意输出一条。路径的表达方式可参考样例。

f[i][j]=Min{f[i][j],f[i][j+1]+a[i][j],f[i][j-1]+a[i][j]}

这个初看不是很好写,f[i][j]与f[i][j+1]和f[i][j-1]都有关,其实只要循环两次,即第一次从左到右,每次f[i][j]只与f[i][j-1]比较,第二次从右到左,每次f[i][j]只与f[i][j+1]比较,就可以了。

代码:

#include<iostream>
#include<fstream>

using namespace std;

int dp[101][501];
int a[101][501];
int road[101][501];
int n,m;

void print(int s,int t){
	if(road[s][t]!=0)
	{
		if(road[s][t]==t)
			print(s-1,road[s][t]);
		else
			print(s,road[s][t]);
		cout<<road[s][t]<<endl;
	}
	
}

void read(){
//	ifstream cin("in.txt");
	int i,j,k;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			scanf("%d",&a[i][j]);
	for(i=1;i<=m;i++)
	{
		dp[1][i]=a[1][i];
		
	}
	for(i=2;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			dp[i][j]=dp[i-1][j]+a[i][j];
			road[i][j]=j;
		}

		for(j=2;j<=m;j++)
		{
			if(dp[i][j]>dp[i][j-1]+a[i][j])
			{
				dp[i][j]=dp[i][j-1]+a[i][j];
				road[i][j]=j-1;
			}
		}
		for(j=m-1;j>=1;j--)
		{
			if(dp[i][j]>dp[i][j+1]+a[i][j])
			{
				dp[i][j]=dp[i][j+1]+a[i][j];
				road[i][j]=j+1;
			}
		}
	}
	int res=dp[n][1];
	j=1;
	for(i=1;i<=m;i++)
		if(res>dp[n][i])
		{
			res=dp[n][i];
			j=i;
		}
	print(n,j);
	cout<<j<<endl;
}

int main(){
	read();
	return 0;
}

posted on 2011-05-01 15:33  宇宙吾心  阅读(513)  评论(0)    收藏  举报

导航