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;
}
浙公网安备 33010602011771号