您的位置:首页 > 大数据 > 人工智能

soj 2505: The County Fair(离散化 + 记忆化搜索)

2015-11-06 14:31 471 查看
@(K ACMer)

题意

有n个展台,你初始时刻在1号展台,时间为0.然后每个展台都会在一个固定的时间p(i)(0<p(i)<1e9)发奖品,从起点出发,你能前往任何展台,但是必须在该点等到p(i)时间拿到奖品,然后再离开,从每两个展台相互之间的转移需要时间T(i,j).问你最多可以得到多少个奖品.

(注:这里除了没有必要在第一个展台待到它发奖品的时间,其它都要).

分析:

我们很容易想到一个暴力搜索dfs(a,t)=min(dfs(j,p(a)+T(a,j))+1)(j=0....n|j!=a),只需要记忆化一下,但是这里记忆化不可行,因为p(i)的值太大了,数组存不下,所以我们先离散化一下.

离散的时候排序,去重一下即可.

code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int mod = int(1e9) + 7, INF = 1e10, maxn = 4e2 + 40;
int n, G[maxn][maxn], p[maxn], maxp, hashs[maxn], m, num, dp[maxn][maxn];

int getid(int x) {
return lower_bound(hashs, hashs + num, x) - hashs;
}

int dfs(int a, int t) {
if (t > p[a]) return 0;
int tt = getid(t);
if (dp[a][tt] != -1) return dp[a][tt];
int maxs = 0;
for (int i = 0; i < n; i++) {
if (i == a) continue;
maxs = max(maxs, dfs(i, p[a] + G[a][i]));
}
return dp[a][tt] = maxs + 1;
}

int main(void) {
while (~scanf("%d", &n)) {
m = 0;
memset(dp, -1, sizeof(dp));
for (int i = 0; i < n; i++)
scanf("%d", &p[i]), hashs[m++] = p[i];
sort(hashs, hashs + m);

num = 1;
for (int i = 1; i < m; i++)
if (hashs[i] != hashs[i - 1]) hashs[num++] = hashs[i];

for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &G[i][j]);
int ans = dfs(0, p[0]);
for (int i = 1; i < n; i++) {
ans = max(ans, dfs(i, G[0][i]));
}
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: