P2196 挖地雷
题目链接:https://www.luogu.com.cn/problem/P2196
思路
没错,我又再重学dp。又开始做水题了。
这个题数据量很小,可以直接把图进行遍历。每次开始的点分别是1~N。dp[v] = max(dp[v],dp[u] + w[v])
代码
#include<bits/stdc++.h> #define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define debug freopen("in.txt","r",stdin),freopen("out.txt","w",stdout); #define PI acos(-1) #define fs first #define sc second using namespace std; typedef long long ll; typedef pair<int,int> pii; const int maxn = 1e3+10; using namespace std; int N,ans,cur,Ed; int w[maxn],dp[maxn],from[maxn]; vector<int> order; int h[maxn],e[maxn],ne[maxn],idx; void add(int a,int b){ e[++idx] = b,ne[idx] = h[a],h[a] = idx; } void dfs(int u){ if(dp[u] > cur) cur = dp[u],Ed = u; for(int i = h[u];i;i = ne[i]){ int v = e[i]; if(dp[u] + w[v] > dp[v]){ dp[v] = dp[u] + w[v]; from[v] = u; } dfs(v); } } void save_ans(){ if(cur > ans){ order.clear(); ans = cur; while(from[Ed]){ order.push_back(Ed); Ed = from[Ed]; } order.push_back(Ed); } } int main(){ // debug; ios; cin>>N; for(int i = 1;i<=N;i++) cin>>w[i]; for(int i = 1;i<=N-1;i++){ for(int j = i+1;j<=N;j++){ int t;cin>>t; if(t) add(i,j); } } for(int i = 1;i<=N;i++) { memset(dp,0,4*N+10); memset(from,0,4*N+10); cur = 0; dp[i] = w[i]; dfs(i); save_ans(); } for(int i = order.size()-1;i>=0;i--) cout<<order[i]<<" "; cout<<'\n'; cout<<ans<<'\n'; return 0; }