- a:原数组
- e:描述关系:i->j
- f:表示第i个结尾的最大值
- from:表示最大值的来源
- ansi:表示答案来源
- 栈sk:用于把顺序倒过来
思路:从小到大的顺序求出以各个点结尾处的最大值
code
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
const int maxn=30;
int n,a[maxn],f[maxn],from[maxn],ans=0,ansi,e[maxn][maxn];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
scanf("%d",&e[i][j]);
}
}
for(int i=1;i<=n;i++){
int k;
for(int j=1;j<i;j++)
if(e[j][i]&&f[j]>f[i]) f[i]=f[j],k=j;
f[i]+=a[i],from[i]=k;
if(f[i]>ans) ans=f[i],ansi=i;
}
stack<int>sk;
for(int i=ansi;i;i=from[i]) sk.push(i);
while(!sk.empty()){printf("%d ",sk.top());sk.pop();}
printf("\n%d\n",ans);
return 0;
}