P2196 挖地雷
阿新 • • 發佈:2020-12-08
題目描述
在一個地圖上有NN個地窖(N \le 20)(N≤20),每個地窖中埋有一定數量的地雷。同時,給出地窖之間的連線路徑。當地窖及其連線的資料給出之後,某人可以從任一處開始挖地雷,然後可以沿著指出的連線往下挖(僅能選擇一條路徑),當無連線時挖地雷工作結束。設計一個挖地雷的方案,使某人能挖到最多的地雷。
輸入格式
有若干行。
第11行只有一個數字,表示地窖的個數NN。
第22行有NN個數,分別表示每個地窖中的地雷個數。
第33行至第N+1N+1行表示地窖之間的連線情況:
第33行有n-1n−1個數(00或11),表示第一個地窖至第22個、第33個、…、第nn個地窖有否路徑連線。如第33行為1 1 0 0 0 … 011000…0,則表示第11個地窖至第22個地窖有路徑,至第33個地窖有路徑,至第44個地窖、第55個、…、第nn個地窖沒有路徑。
第44行有n-2n−2個數,表示第二個地窖至第33個、第44個、…、第nn個地窖有否路徑連線。
… …
第n+1n+1行有11個數,表示第n-1n−1個地窖至第nn個地窖有否路徑連線。(為00表示沒有路徑,為11表示有路徑)。
輸出格式
有兩行
第一行表示挖得最多地雷時的挖地雷的順序,各地窖序號間以一個空格分隔,不得有多餘的空格。
第二行只有一個數,表示能挖到的最多地雷數。
輸入輸出樣例
輸入 #1複製
5 10 8 4 7 6 1 1 1 0 0 0 0 1 1 1
輸出 #1複製
1 3 4 5 27
思路:這是dp入門題。
dp[i]:表示以第i個洞結尾做多有幾個地雷。
dp[i]=max(dp[i],dp[j]+dp[i]); 其中(i,j)有連線。
最後去dp[1-n]中最大的一個。
此題需要記錄路徑,用一個數組記錄前驅,遞迴輸入即可。
#include <bits/stdc++.h> using namespace std; int f[50],a[50],mark[50][50],path[50],g[50]; void oprint(int x){//遞迴輸出 if(path[x]==-1){ //前驅為-1說明找到路徑的開端了 cout<<x<<" "; return; } oprint(path[x]);//先輸出前驅 cout<<x<<" "; } int main() { int n,x,id; 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>>x; mark[i][j]=mark[j][i]=x; } } memset(path,-1,sizeof(path)); int ans=0; for(int i=1; i<=n; i++){//f[i]表示以i為結尾的地雷個數 f[i]=a[i];//至少自己的洞有a[i]個 int ma=0,k=0; for(int j=1; j<=n; j++){//找到一個最大的f[j] if(i!=j&& mark[i][j]&&f[j]>ma){ path[i]=j;//記錄i的前驅 ma=f[j]; k=1; } } if(k) f[i]+=ma; if(ans<f[i]){ ans=max(f[i],ans); id=i; } } oprint(id); cout<<endl; cout<<ans<<endl; return 0; } //拓撲排序