书接上回,牛妹组织春游,有一个有趣的项目是挖番薯。聪明的牛妹拿到了一个表明了番薯洞的地图,每个番薯洞中有一定数量的番薯。同时,我们知道番薯洞的连接路径,并规定路径是单向且小序号指向大序号,也无环。可以从任意一处开始挖,然后沿着连接往下挖(仅能选择一条路径),当无连接时,结束。
设计一种挖番薯的方案,使得可以挖到更多的番薯。
输出路径。
思路:一开始我是dfs记忆化搜索写了好久好久还改了很久,后面看大佬代码,原来可以直接记录每个点的前缀节点,根据前缀来推该点的最大值,因为该路都是由小节点指向大节点,故可以保证每个节点处理时其前缀节点都已经处理完全。
‘
class Solution {
public:
/**
*
* @param potatoNum int整型vector 依次表示序号为1,2,3..的番薯洞各有多少个番薯
* @param connectRoad int整型vector<vector<>> 每个一维数组[x,y]表示从第x号番薯洞到第y号有路
* @return string字符串
*/
string digSum(vector<int>& a, vector<vector<int> >& b) {
vector<vector<int>> g(a.size()+5);
for(int i=0;i<b.size();i++)
{
//记录每个点的前缀节点
g[b[i][1]].push_back(b[i][0]);
}
vector<int> pre(a.size()+5,-1);//记录最优前缀节点
vector<int> dp(a.size()+5,0);
for(int i=1;i<=a.size();i++)
{
for(int j=0;j<g[i].size();j++)
{
if(dp[g[i][j]]>dp[i])
{
dp[i]=dp[g[i][j]];
pre[i]=g[i][j];
}
}
dp[i]+=a[i-1];
}
int maxz=0;
int def=0;
for(int i=1;i<=a.size();i++)
{
if(dp[i]>maxz)
{
maxz=dp[i];
def=i;
}
}
vector<int> ans;
string str="";
while(def!=-1)
{
ans.push_back(def);
def=pre[def];
}
reverse(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++)
{
if(i==0)
{
str+=to_string(ans[i]);
}
else
{
str+='-';
str+=to_string(ans[i]);
}
}
return str;
}
};