题目传送门,走你~~~
分析:经典的DP题。本题需要在道路畅通的地窖中,尽可能的挖的多的雷。即本地窖中的雷加上你后续可以去到的地窖中挖到的雷的总和。因而状态转移方程:sum[i] = max(sum[i],sum[j]+a[i])
//a[i]本地窖中雷。j>i;sum[i]上一个地窖中。sum[j]+a[i]去到下一地窖挖到雷的总和
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 330;
/*
1.用a数组存储每个地窖中地雷的个数。
2.用f数组记录路径
3.tt数组记录是否可以有通过去下一个地窖的路径。
4.sum数组记录和的值
*/
int a[maxn],f[maxn],tt[maxn][maxn],sum[maxn];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];//每个地窖地雷的个数 。
}
for (int i = 1; i < n; i++)
{
for (int j = i+1; j <= n; j++)
{
cin >> tt[i][j];//输入连接路径
}
}
memset(sum, 0, sizeof(sum));
memset(f, -1, sizeof(f));
for (int i = n; i >= 1; i--)
{
sum[i] = a[i];
for (int j = i+1; j <= n; j++)
{
if (tt[i][j] && sum[j] + a[i] > sum[i])
{ //路径畅通,递推看一下第i行的那个元素更大,取更大的值。
sum[i] = sum[j] + a[i];
f[i] = j;
}
}
}
int k = 0;
for (int i = 0; i <= n; i++)
{//找出最大的值并记录其开始的路径。
if (sum[i] > sum[k])
{
k = i;
}
}
int maxx = sum[k];
cout << k;
k = f[k];
while (k != -1)
{
cout << " " << k;
k = f[k];
}
cout << endl;
cout << maxx << endl;
return 0;
}