1、题目描述
假设某款芯片上有M*N个计算单元,并对计算单元进行编号,其最力上角计 印单元编号为(0.0),其最右下角编号为(M-1, N-1).现有个计算任 务,需要从(0,0) 开始计算,到(M-1,N-1)结束,并假定只有当前任务执行完成后,才将该任务推送到与其编号相邻的计算单元进行计算,同时每个计算单元仅计算次。给定每个计算单元计算某个任务的计算代价,从(0,0)到(M-1,N-1)有若干条计算路径,求计算代价总和最大的路径上其平均计算代价。
说明: 计算任务只能在相邻的计算单元之间迁移,也就是只能上下左右移动,而不能通过斜角移动。
2、示例
输入:
3 3
1 2 20
2 20 5
2 2 5
总共输入M+1行,第一行输入两个正整数, 分别为M和N;第j行(2<=j<=M+1)行输入N个正整数(取值范围0~10^6)。
输出:
7
输出为平均代价,返回一个正整数(舍弃小数点后面的数,无需四舍五入)。
3、题解
基本思想:递归,从(0,0)出发递归遍历每一种情况,上下左右四个方向移动,更新四个方向格子的sum和steps并且沿着该方向格子继续递归,同时visited[i][j]=1避免重复经过,最后i=M-1&&j=N-1,更新最大平均路径代价res=max(res,dp[i][j].sum/dp[i][j].steps),结束递归。
#include<iostream>
#include<vector>
using namespace std;
int M,N;
struct Node{
int steps;
int sum;
};
vector<vector<int>> compute_cost;
int res=0;
void dfs(int i,int j,vector<vector<int>> visited,vector<vector<Node>> dp)
{
if(visited[i][j]==1)
return;
visited[i][j]=1;
if(i==M-1&&j==N-1)
{
res=max(res,dp[i][j].sum/dp[i][j].steps);
return;
}
int cursum,cursteps;
if(i-1>=0)
{
dp[i-1][j].sum=dp[i][j].sum+compute_cost[i-1][j];
dp[i-1][j].steps=dp[i][j].steps+1;
dfs(i-1,j,visited,dp);
}
if(i+1<M)
{
dp[i+1][j].sum=dp[i][j].sum+compute_cost[i+1][j];
dp[i+1][j].steps=dp[i][j].steps+1;
dfs(i+1,j,visited,dp);
}
if(j-1>=0)
{
dp[i][j-1].sum=dp[i][j].sum+compute_cost[i][j-1];
dp[i][j-1].steps=dp[i][j].steps+1;
dfs(i,j-1,visited,dp);
}
if(j+1<N)
{
dp[i][j+1].sum=dp[i][j].sum+compute_cost[i][j+1];
dp[i][j+1].steps=dp[i][j].steps+1;
dfs(i,j+1,visited,dp);
}
}
int main()
{
cin>>M>>N;
vector<vector<Node>> dp;
vector<vector<int>> visited(M,vector<int>(N,0));
for(int i=0;i<M;i++)
{
vector<int> tmp;
vector<Node> tmp1;
for(int j=0;j<N;j++)
{
int x;
Node y;
y.steps=1;
y.sum=0;
cin>>x;
tmp.push_back(x);
tmp1.push_back(y);
}
compute_cost.push_back(tmp);
dp.push_back(tmp1);
}
dp[0][0].sum=compute_cost[0][0];
dp[0][0].steps=1;
dfs(0,0,visited,dp);
cout<<res<<endl;
}