挖地雷问题
(P3.pas/c/cpp)
来源:NOIP1996(提高组)第三题(有改动)
【问题描述】
在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。
当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
【输入文件】
N:(表示地窖的个数)
W1,W2,W3,……WN
(表示每个地窖中埋藏的地雷数量)
A12…………… . A1N
A23…………..A2N
……..
AN-1N
【输出文件】
K1--K2--……….KV
(挖地雷的顺序)
MAX
(挖地雷的数量)
【输入样例】 //////整一个类数字三角形
5
10,8,4,7,6
1 1 1 0
0 0 0
1 1
1
【输出样例】
1->3->4->5
max=27
思路:
dp[ i ]表示 以i为起点的挖到最多的雷数;
dp[ i ]=w[ i ]+max{ dp[ j ] | (i ,j )通路 };
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #define N 210 using namespace std; int w[N]; int dp[N]; struct node{ int to; int next; }edge[N*N]; int pre[N]; int path[N]; int main() { int n; while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof dp); memset(pre,-1,sizeof pre); memset(path,0,sizeof path); for(int i=1;i<=n;i++) scanf("%d",w+i); int v; int cnt=0; for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) { scanf("%d",&v); //邻接表 if(v) { edge[cnt].to=j; edge[cnt].next=pre[i]; pre[i]=cnt++; } } dp[n]=w[n]; int maxx=0; int u; int p; for(int i=n-1;i>=1;i--) //dp { u=pre[i]; while(u) { v=edge[u].to; if(dp[v]>maxx) { maxx=dp[v]; p=v; } u=edge[u].next; } path[i]=p; //路<span style="font-family:Times New Roman;">径记录</span> dp[i]=maxx+w[i]; } int k=1; for(int i=1;i<=n;i++) if(dp[i]>dp[k]) k=i; maxx=dp[k]; printf("%d",k); k=path[k]; while(k) { printf("->%d",k); k=path[k]; //printf("%d",k); } cout<<endl<<maxx<<endl; } return 0; }
时间: 2024-10-18 05:44:16