原文链接
看到上面这个博客中的一道面试题,如下
有一个n*n的棋盘,上面有m个糖果,最开始有一个人在棋盘左上角,他可以向左向右或者向下移动,但不能向上移动,问他最少需要多少步吃完所有糖果。
写一下自己的思路和代码,因为没有OJ可以验证,不知道对错,暂且记录一下。
思路:动态规划求解
动规计算如果从该位置进入下一行(本行及上面所有行的糖果均已拿到),此时走的最少步数。
我们只要是到一行的进入位置和离开位置,根据糖果的位置拿到这一行糖果的步数就是固定的,所以计算dp[i][j]就是从i-1行的每一个位置当做入口,找到最小的步数即为dp[i][j]的值。
糖果的位置 只需要记录每一行最左和最右糖果的位置即可。
注意:
向下走的那一步要记得加上。
动态规划的空间优化,可以使用两行的数组。
可能存在一整行都没有糖果的情况。
#include<iostream>
#include<string>
#include<sstream>
#include<fstream>
#include<algorithm>
#include<iterator>
#include<vector>
using namespace std;
vector<vector<int>> input(){
string row;
vector<vector<int>> res;
while(getline(cin,row)){
istringstream ss(row);
istream_iterator<int> eos;
istream_iterator<int> beg(ss);
vector<int> tmp;
copy(beg,eos,back_inserter(tmp));
res.push_back(move(tmp));
}
return res;
}
int min_steps(const vector<vector<int>>& data){
if(data.empty())
return -1;
int row = data.size();
int col = data[0].size();
int est[100000][2];
for(int i=0;i<row;i++)
{
est[i][0]=col;
est[i][1]=-1;
}
//est[0][0]=0;
//est[0][1]=0;
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
if(data[i][j]) continue;
if(j<est[i][0]) est[i][0]=j;
if(j>est[i][1]) est[i][1]=j;
}
}
for(int i=0;i<row;i++)
{
cout<<est[i][0]<<" "<<est[i][1]<<"est"<<endl;
}
if(row==1)
{
return est[0][1];
}
int m[2][2];
m[0][0]=2*est[0][1]-est[0][0];
m[0][1]=est[0][1];
cout<<m[0][0]<<" "<<m[0][1]<<"m[0]"<<endl;
int step=0;
int a=m[0][0],b=m[0][1];
for(int i=1;i<row;i++)
{
step=1-step;
if(est[i][1]<est[i][0])
{
m[step][0]=m[1-step][0]+1;
m[step][1]=m[1-step][1]+1;
est[i][0]=est[i-1][0];
est[i][1]=est[i-1][1];
cout<<m[step][0]<<" "<<m[step][1]<<"m[step]continue"<<endl;
continue;
}
m[step][0] = est[i][1]-est[i][0]+min(m[1-step][0]+abs(est[i][1]-est[i-1][0]),m[1-step][1]+abs(est[i][1]-est[i-1][1]))+1;
m[step][1] = est[i][1]-est[i][0]+min(m[1-step][0]+abs(est[i][0]-est[i-1][0]),m[1-step][1]+abs(est[i][0]-est[i-1][1]))+1;
cout<<est[i][0]<<" "<<est[i][1]<<" "<<est[i-1][0]<<" "<<est[i-1][1]<<"estfor"<<endl;
cout<<m[step][0]<<" "<<m[step][1]<<"m[step]"<<endl;
a=m[step][0];
b=m[step][1];
}
return min(a,b);
}
int main(){
cout << min_steps(input()) << endl;
return 0;
}