题解:
动态转移方程:f[i]=max(f[j])+w[i];
i:表示当前点
j:表示可以到达i点的上一个点
w[i]:表示第i点的地雷数
f[i]表示起点到i点的爆炸最大地雷数
至于记录爆炸顺序可以这样处理
q[i]=j(表示第i点是由j点过来的)
在动态规划过程中就可以记录,但是输出需要逆向,所以我用了递归逆向输出
#include<cstdlib>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int n,a[25][25];
int f[25],w[25],q[25];
int maxn=0,maxi=0;
//递归输出挖地雷顺序
void ft(int x){
if(x==0)return;
ft(q[x]);
printf("%d ",x);
}
int main()
{
scanf("%d",&n);
//输入地雷数
for(int i=1;i<=n;i++){
scanf("%d",&w[i]);f[i]=w[i];
}
//邻接矩阵
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
scanf("%d",&a[i][j]);
}
}
//动态规划
for(int i=1;i<=n;i++)
{
for(int j=1;j<i;j++)
{
if(a[j][i])
{
if(f[j]+w[i]>f[i])
{
f[i]=f[j]+w[i];
q[i]=j;//记录挖地雷顺序
}
}
}
}
//求出最大值和最大值下标
for(int i=1;i<=n;i++){
if(maxn<f[i]){
maxn=f[i];
maxi=i;
}
}
ft(maxi);//递归
printf("\n%d\n",maxn);
return 0;
}