题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1224
题目解析: 这道题可以用DFS或者DP解决,
第一直观反应是DFS,广度搜索,
void dfs(int u, int dep, int val)
第一个参数 u是已经到达的城市, 参数dep是当前路径长度,val是到当前城市累计的兴趣值。
从 dfs(1, 1, 0) 开始,即从第一个城市开始,路径是1,按题意起始第一个城市兴趣值是0;
dfs搜索结束条件是u走到第n+1城市即回到开始起点城市,按题意1和n+1两个值代表同一个起点城市。
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <memory>
using namespace std;
const int maxn = 200;
int G[maxn][maxn]; //储存图
int ins[maxn]; //兴趣点
int circle[maxn]; //储存执行中的路径
int sum; //总的值
int t, n, m, x, y;
int ans[maxn]; //储存答案兴趣值最大的路径
int len;
void dfs(int u, int dep, int val) {
if (u == n + 1) {
if (val > sum) //判断
{
sum = val;
for (int i = 0; i < dep; i++) ans[i] = circle[i];
len = dep;
}
return;
}
for (int i = u + 1; i <= n + 1; i++) //从u+1开始
if (G[u][i]) { //存在航班
circle[dep] = i;
dfs(i, dep + 1, val + ins[i]);
}
}
int main() {
int case = 0;
scanf("%d", &t);
while (t--) {
memset(G, 0, sizeof(G)); //初始化
memset(ins, 0, sizeof(ins));
memset(circle, 0, sizeof(circle));
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &ins[i]);
scanf("%d", &m);
for (int i = 1; i <= m; i++) //建立图
{
scanf("%d %d", &x, &y);
G[x][y] = 1;
}
sum = 0;
circle[0] = 1;
dfs(1, 1, 0);
printf("CASE %d#\npoints : %d\n", ++case, sum);
printf("circuit : ");
for (int i = 0; i <= len - 2; i++) printf("%d->", ans[i]);
printf("%d\n", ans[len - 1] - n);
if (t > 0) printf("\n");
}
}
PS:另一个思路,本题如果用DP解决,则是定义一个二维数组,每一行存储走一步的所有可能结果,下一行基于上一行多走一步推出递推公式。