思路:动态规划,正推。题目画出来其实是一个有向图,每个节点都是要往下走的,当然必定从第一个地窖开始挖,可以遍历当前地窖到后续所有地窖,查看i到j是否有路径,如果有路径并且以j地窖为终点的最大地雷小于i地窖加上j地窖的地雷数,就更新最大地雷数和路径。
状态表示:dp[i]表示以第i个地窖为终点的最大地雷数
状态方程:dp[j]=dp[i]+a[i]
#include<iostream>
using namespace std;
const int N=250;
int a[N];//地窖地雷数量
int dp[N];//以第i个地窖为终点的最大地雷
int path[N]; //记录顺序
int g[N][N];//记录连接
void dfs(int x)
{
//递归搜索前驱,正序输出
if(path[x])dfs(path[x]);
cout<<x<<" ";
}
int main()
{
int n,res=0,pos;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
dp[i]=a[i];//初始化
}
for(int i=1;i<=n-1;i++)
{
for(int j=i+1;j<=n;j++)
{
cin>>g[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(g[i][j]&&dp[j]<dp[i]+a[j])
{
//更新最值
dp[j]=dp[i]+a[j];
path[j]=i;//记录前驱
}
}
}
for(int i=1;i<=n;i++)
{
if(dp[i]>res)
{
res=dp[i];
pos=i;//记录取得最大值的位置
}
}
dfs(pos);
cout<<endl<<res;
return 0;
}