P2196 [NOIP1996 提高组] 挖地雷 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
先放个题目链接,这道题是我第一次做到试着储存dp路径的,不是很难想但是实现花了一段时间,顺带发现了一个小坑,for(t = 1;t<=a;t++),在for循环的后续使用的t=a+1而不是a了
#include<bits/stdc++.h>
using namespace std;
const int maxn = 30;
int num[maxn];
int pos[maxn][maxn];
int dp[maxn]; //i地窖的最大炸弹
int lu[maxn][maxn];
int main(){
int n;
scanf("%d",&n);
int ans = 0;
for(int i =1;i<=n;i++)
scanf("%d",&num[i]);
for(int i = 1;i<=n;i++)
for(int j = i+1;j<=n;j++)
scanf("%d",&pos[i][j]); //矩形连通图,i到j
for(int i =1;i<=n;i++) {
dp[i] = num[i];
lu[i][0] = 1; //0储存当前几个地窖
lu[i][1] = i; //储存当前走的位置
}
for(int i = 2;i<=n;i++)
for(int j = i-1;j>=1;j--){
if(pos[i-j][i]==0)
continue; //先保证这个地窖是可以到达的
if(dp[i-j]+num[i]>dp[i]){
dp[i] = dp[i-j]+num[i];
for(int t = 1;t<=lu[i-j][0];t++) //注意,如果t不是全局变量的话,这个地方t在到达lu[i-j]的时候还会加一次(虽然不会进入循环)
lu[i][t] = lu[i-j][t];
lu[i][lu[i-j][0]+1] = i;
lu[i][0] = lu[i-j][0]+1; //如果当前的路线大于原路线的最大值,那么需要更新原路径和dp值
}
}
int mx = 1;
for(int i = 1;i<=n;i++){
if(dp[i]>dp[mx])
mx = i;
}
for(int i = 1;i<=lu[mx][0];i++){
printf("%d",lu[mx][i]);
if(i==lu[mx][0])
printf("\n");
else
printf(" ");
}
printf("%d",dp[mx]);
}
//每个地窖只有向后连的路线,单向不可回头,同时需要储存路径