01背包
#include<iostream>
using namespace std;
int n;
int v[25];//存放当前地窖的地雷数
int dp[25];//dp数组
int w[25][25];//状态,能否通行
int count[25];//记录路径
int main(){
cin >> n;
int i,j;
for(i = 1; i <= n; ++i){//初始化数组
cin >> dp[i];
v[i] = dp[i];
count[i] = i;
}
for(i = 1; i <= n-1; ++i){//读入状态
for(j = i+1;j <= n; ++j){
cin >> w[i][j];
}
}
for(i = 1; i <= n-1; ++i){//开始dp
for(j = n;j >= i+1; --j){
if(w[i][j]){//可以从i到j
dp[j] = max(dp[j],dp[i]+v[j]);//转移方程:前面到j的地雷数和到i的地雷数+j里有的地雷数比较
//如果是从i到j的话,存储编号
if(dp[j] - v[j] == dp[i])count[j] = count[i]*100 + j;//一定要×100,否则最后一个样例无法通过
}
}
}
int max = 1;
for(i = 2; i <= n; ++i){//寻找dp数组中的最大值
if(dp[max] < dp[i])max = i;
}
int ans[25];//输出编号的数组
int num = 0;
while(count[max]){//求逆序
ans[num++] = count[max] % 100;
count[max] /= 100;
}
cout << ans[num-1];
for(i = num-2; i >= 0; --i){//输出编号
cout << " " << ans[i];
}
cout << endl;
cout << dp[max];//输出最大值
return 0;
}