P2196 挖地雷
题目背景
NOIp1996提高组第三题
题目描述
在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
输入输出格式
输入格式:输入文件mine.in有若干行。
第1行只有一个数字,表示地窖的个数N。
第2行有N个数,分别表示每个地窖中的地雷个数。
第3行至第N+1行表示地窖之间的连接情况:
第3行有n-1个数(0或1),表示第一个地窖至第2个、第3个、…、第n个地窖有否路径连接。如第3行为1 1 0 0 0 … 0,则表示第1个地窖至第2个地窖有路径,至第3个地窖有路径,至第4个地窖、第5个、…、第n个地窖没有路径。
第4行有n-2个数,表示第二个地窖至第3个、第4个、…、第n个地窖有否路径连接。
… …
第n+1行有1个数,表示第n-1个地窖至第n个地窖有否路径连接。(为0表示没有路径,为1表示有路径)。
输出格式:输出文件wdl.out有两行数据。
第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。
第二行只有一个数,表示能挖到的最多地雷数。
输入输出样例
输入样例#1:
5 10 8 4 7 6 1 1 1 0 0 0 0 1 1 1
输出样例#1:
1 3 4 5 27
先挂上代码,有几个地方细思极恐,需要仔细想想
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #define max(a, b) ((a) > (b)) ? (a) : (b); #define min(a, b) ((a) < (b)) ? (b) : (a); inline int read() { int x = 0;char ch = getchar();char c = ch; while(ch > '9' || ch < '0')c = ch,ch = getchar(); while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0',ch = getchar(); if(c == '-')return -1 * x; return x; } const int INF = 0x3f3f3f3f; const int MAXN = 20 + 10; int n; int b[MAXN][MAXN],num[MAXN],f[MAXN],path[MAXN]; int a[MAXN]; int cnt; int main() { n = read(); for(int i = 1;i <= n;i ++) { num[i] = read(); } for(int i = 1;i <= n - 1;i ++) { int temp = n - i; for(int j = 1;j <= temp;j ++) { b[i][j + i] = read(); } } f[n] = num[n]; for(int i = n - 1;i >= 1;i --) { f[i] = num[i]; for(int j = n;j >= i ;j --) { if(b[i][j] && f[i] < f[j] + num[i]) { f[i] = f[j] + num[i]; path[i] = j; } } } int ans,max = -1; for(int i = 1;i <= n;i ++) { if(max < f[i]) { ans = i; max = f[i]; } } while(ans) { printf("%d ", ans); ans = path[ans]; } printf(" %d", max); return 0; }