hdu 4517 floyd+记忆化搜索

2024-09-09 15:58
文章标签 搜索 记忆 hdu floyd 4517

本文主要是介绍hdu 4517 floyd+记忆化搜索,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意:

有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。

访问每个景点需要时间cost_i,每个景点的访问价值为value_i。

点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。

走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。

现在求,从起点出发,到达终点,在时间限制内,能得到的最大价值为多少。

如果不能从s到达e,则输出0。


解析:

首先应该走到一个点可以选择访问或者不访问,所以可以用floyd求出点与点之间最近的距离为多少。

然后dp[ i ] [ j ] [ k ] 表示的是,当前走到 i 点,前一个点的价值为 j ,并且还有剩余时间 k 的最大价值。

详见代码。


代码:

#pragma comment(linker, "/STACK:1677721600")
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cassert>
#include <iostream>
#include <algorithm>
#define pb push_back
#define mp make_pair
#define LL long long
#define lson lo,mi,rt<<1
#define rson mi+1,hi,rt<<1|1
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define FIN freopen("in.txt", "r", stdin)
#define FOUT freopen("out.txt", "w", stdout)
#define rep(i,a,b) for(int i=(a); i<=(b); i++)
#define dec(i,a,b) for(int i=(a); i>=(b); i--)using namespace std;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double ee = exp(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 100 + 10;
const int maxt = 300 + 10;
const double pi = acos(-1.0);
const LL iinf = 0x3f3f3f3f3f3f3f3f;int readT()
{char c;int ret = 0,flg = 0;while(c = getchar(), (c < '0' || c > '9') && c != '-');if(c == '-') flg = 1;else ret = c ^ 48;while( c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c ^ 48);return flg ? - ret : ret;
}int n, m, t, s, e;
int g[maxn][maxn];
int dp[maxn][maxn][maxt];
int cost[maxn];
int value[maxn];void floyd()
{rep(i, 0, n - 1){g[i][i] = 0;}rep(k, 0, n - 1){rep(i, 0, n - 1){rep(j, 0, n - 1){g[i][j] = Min(g[i][j], g[i][k] + g[k][j]);}}}
}int dfs(int u, int preVal, int timeLeft)
{if (g[u][e] > timeLeft)return -inf;int& res = dp[u][preVal][timeLeft];if (res != -1)return res;res = 0;rep(i, 0, n - 1){if (preVal < value[i]){res = Max(res, dfs(i, value[i], timeLeft - g[u][i] - cost[i]) + value[i]);}}return res;
}int main()
{
#ifdef LOCALFIN;
#endif // LOCALint ncase = readT();int ca = 1;while (ncase--){scanf("%d%d%d%d%d", &n, &m, &t, &s, &e);mem(dp, -1);mem(g, inf);rep(i, 0, n - 1){cost[i] = readT();}rep(i, 0, n - 1){value[i] = readT();}rep(i, 0, m - 1){int u = readT();int v = readT();int w = readT();g[u][v] = g[v][u] = Min(g[u][v], w);}floyd();int ans = dfs(s, 0, t);printf("Case #%d:\n", ca++);printf("%d\n", ans == -inf ? 0 : ans);}return 0;
}


这篇关于hdu 4517 floyd+记忆化搜索的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1151622

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

uva 10099(floyd变式)

题意: 有一个导游要带着一群旅客从一个城市到达另一个城市,每个城市之间有最大的旅客流量限制。 问最少几趟能将这些旅客从一个城市搞到另一个城市。 解析: 用floyd找出最小流量中的最大边,然后次数就是   ceil(总人数 / 最大承载量 - 1),-1的意思是导游每次也要在车上。 ps.老司机哭晕在厕所 代码: #include <iostream>#includ

uva 10048(floyd变式)

题意: 求两个点之间经过的路径中最大噪声最小的值。 解析: floyd的变式,每次取g[i][k] g[k][j]中的大边与当前边g[i][j]比较,取小。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#includ