题意:

给出一个有\(N\)个顶点\(M\)条有向边的图,起点为\(1\),终点为\(N\)。

每条边有经过的时间,和经过这条边的花费。一开始你有\(R\)元钱,要在\(T\)时间内赶到终点去约会。

每次到一个顶点(起点和终点除外),该顶点标好了价格,你可以:

  • 在这里购买一袋盐
  • 在这里出售一袋盐
  • 或者什么都不做

在整个交易的过程中你的钱不能是负数,你身上携带的盐不能超过\(B\)袋。

更要命的是,你还有个手持电子设备,你可以在\(K\)个平行时空中穿梭,你本来所在的平行时空的编号为\(0\)。

具体来说就是,花费\(1\)单位时间,你可以从第\(i\)个平行时空穿越到第\((i+1)%K\)个平行时空。

所有平行时空的地图一样,每条边花费的时间以及费用也一样,但是每个点交易盐的价格会有变化。

为了避免一起混乱,你只能到自己原来所在的平行时空的点\(1\)和\(N\)。

求可以及时赶到约会地点的前提下,最多能赚多少钱。

分析:

这题可以用\(DP\)来做,设计一个状态:\(d(t, dim, u, b, c)\)表示正在第\(dim\)个平行时空的\(u\)顶点花费了\(t\)时间,身上有\(b\)袋盐,\(c=0\)表示还没有进行交易,\(c=1\)表示已经进行过交易了,所能得到的最多的钱。

那么有下面几种决策:

  • 我们可以在该平行时空下往前走到\(v\)点,转移的条件是身上的钱足够支付路费走这条边的时间不会超过总时间
  • 可以花费\(1\)个单位时间传送到下一个平行时空,转移的条件是不会超出限制时间
  • 我们可以在这买一袋盐,转移条件是身上的钱足够而且之前没有进行过交易
  • 我们还可以卖一袋盐,转移条件是身上至少携带一袋盐而且之前没有进行过交易

代码是用递推的方式写的,但要注意循环顺序。

最后说一下为什么可以\(DP\),其实就是时间一直是递增的,只会有之前的时间的状态更新之后时间的状态。

更详细的说明可以参考这里

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #define REP(i, n) for(int i = 0; i < (n); i++)
  5. using namespace std;
  6. void update(int& a, int b) {
  7. if(b > a) a = b;
  8. }
  9. const int maxn = 100 + 10;
  10. const int maxm = 200 + 10;
  11. struct Edge
  12. {
  13. int v, dist, cost, nxt;
  14. Edge() {}
  15. Edge(int v, int d, int c, int nxt):v(v), dist(d), cost(c), nxt(nxt) {}
  16. };
  17. int ecnt;
  18. Edge edges[maxm];
  19. int head[maxn], nxt[maxm];
  20. void init() {
  21. memset(head, -1, sizeof(head));
  22. ecnt = 0;
  23. }
  24. void AddEdge(int u, int v, int dist, int cost) {
  25. edges[ecnt] = Edge(v, dist, cost, head[u]);
  26. head[u] = ecnt++;
  27. }
  28. int N, M, B, K, R, T;
  29. int price[10][maxn];
  30. int d[210][7][110][7][2];
  31. int main() {
  32. //freopen("6538.txt", "r", stdin);
  33. int Test; scanf("%d", &Test);
  34. for(int kase = 1; kase <= Test; kase++) {
  35. init();
  36. scanf("%d%d%d%d%d%d", &N, &M, &B, &K, &R, &T);
  37. REP(i, K) REP(j, N) scanf("%d", &price[i][j]);
  38. REP(i, M) {
  39. int u, v, t, m; scanf("%d%d%d%d", &u, &v, &t, &m);
  40. u--; v--;
  41. AddEdge(u, v, t, m);
  42. }
  43. //DP
  44. memset(d, -1, sizeof(d));
  45. d[0][0][0][0][0] = R;
  46. int ans = -1;
  47. REP(t, T+1) REP(dim, K) REP(u, N) REP(c, 2) REP(b, B+1) {
  48. int& cur = d[t][dim][u][b][c];
  49. if(cur == -1) continue;
  50. if(dim == 0 && u == N-1) { update(ans, cur); continue; }
  51. //printf("t = %d, dim = %d, u = %d, b = %d, c = %d, cur = %d\n", t, dim, u, b, c, cur);
  52. for(int i = head[u]; ~i; i = edges[i].nxt) {
  53. Edge& e = edges[i];
  54. if(dim != 0 && (e.v == 0 || e.v == N-1)) continue;
  55. if(t + e.dist <= T && cur >= e.cost)
  56. update(d[t + e.dist][dim][e.v][b][0], cur - e.cost);
  57. }
  58. if(t + 1 <= T && u != 0 && u != N-1)
  59. update(d[t + 1][(dim+1) % K][u][b][0], cur);
  60. if(c == 0) {
  61. if(u == 0 || u == N-1) continue;
  62. if(cur >= price[dim][u] && b < B) update(d[t][dim][u][b+1][1], cur - price[dim][u]);
  63. if(b) update(d[t][dim][u][b-1][1], cur + price[dim][u]);
  64. }
  65. }
  66. printf("Case #%d: ", kase);
  67. if(ans == -1) printf("Forever Alone\n");
  68. else printf("%d\n", ans);
  69. }
  70. return 0;
  71. }

LA 6538 Dinner Coming Soon DP的更多相关文章

  1. HDU--4784 Dinner Coming Soon DP+BFS

    题意非常长非常变态.一个人要到他男朋友家,他最初有R元以及T分钟的时间来赶到他男朋友家.有N个房子M条道路,每条道路有须要消耗的时间以及过路费,同一时候还要顺路做食盐生意,起初身上没有食盐,最多带B袋 ...

  2. 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) D.Dinner Bet 概率DP+排列组合

    题目链接:点这里 题意: 1~N标号的球 现在A有C个,B有C个 每次可以随机得到D个不同的球(1~N);问你A或B中的C个球都出现一次的 期望次数 题解: dp[i][j][k]表示 随机出现了i个 ...

  3. DP 题集 2

    关于 DP 的一些题目 String painter 先区间 DP,\(dp[l][r]\) 表示把一个空串涂成 \(t[l,r]\) 这个子串的最小花费.再考虑 \(s\) 字符串,\(f[i]\) ...

  4. ZOJ - 2401 水DP

    最近会多做点巩固基础的题目 #include<iostream> #include<algorithm> #include<cstdio> #include< ...

  5. BZOJ 3107 [cqoi2013]二进制a+b (DP)

    3107: [cqoi2013]二进制a+b Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 995  Solved: 444[Submit][Stat ...

  6. 「BZOJ 4565」「HAOI 2016」字符合并「区间状压DP」

    题意 给一个长度为\(n(\leq 300)\)的\(01\)串,每次可以把\(k(\leq 8)\)个相邻字符合并,得到新字符和一定分数,最大化最后的得分 题解 考虑设计dp:\(dp[S][i][ ...

  7. 2019牛客暑期多校训练营(第七场)-H Pair(数位dp)

    题目链接:https://ac.nowcoder.com/acm/contest/887/H 题意:给定A,B,C,求有多少对(x,y)满足x&y>C或者x^y<C,其中1< ...

  8. 博弈dp入门 POJ - 1678 HDU - 4597

    本来博弈还没怎么搞懂,又和dp搞上了,哇,这真是冰火两重天,爽哉妙哉. 我自己的理解就是,博弈dp有点像对抗搜索的意思,但并不是对抗搜索,因为它是像博弈一样,大多数以当前的操作者来dp,光想是想不通的 ...

  9. 51 Nod 1006 最长公共子序列(LCS & DP)

    原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006 题目分析: 首先先知道LCS问题,这有两种: Long ...

随机推荐

  1. More than one fragment with the name [spring_web] was found. This is not legal ...

    今天在搭建springweb应用环境的时候启动tomcat报错More than one fragment with the name [spring_web] was found. This is ...

  2. 使用Calendar来获取当前日期和时间

    1 package com.java.test; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Calendar; 5 6 pub ...

  3. css hack 浏览器携带自身特有的属性 (二)

    css hack 浏览器携带自身特有的属性,才是我们真正要解决的css 兼容问题. 这里只是分享思路. 举例子: 1 outline,尤其是一些 自带继承特性的属性.这里指的是 隐性的inherite ...

  4. AES加密示例

    最近用到对文本内容进行加密,于是查了一下常用的加密算法: DES(Data Encryption Standard):对称算法,数据加密标准,速度较快,适用于加密大量数据的场合:3DES(Triple ...

  5. [LR]遇到的坑及常用技巧

    解决问题是需要智慧的 1.LR内部问题可以查看帮助文档 一般位于LR安装目录的bin目录下,如下图 打开Troubleshooting.chm文件,比如我们跑场景的过程中报错,报错信息为:-27995 ...

  6. HDU 5501 The Highest Mark (贪心+DP,经典)

    题意: 有n道题目,每道题目的初始分数为Ai,分数每分钟减少Bi,完成此题需要Ci分钟,问在t分钟内最多能获得多少分? 思路: 好题~ 如果没有B的话,就是一道裸的01背包的题目了.每道题目的得分为: ...

  7. SAP CRM和C4C的客户主数据修改历史记录查询

    SAP CRM 随便修改一个字段,比如给Search Term维护值"webpack": Change History assignment block里显示出了这条修改记录: 根 ...

  8. UVA 1615 Highway 高速公路 (区间选点)

    题意:在一条线段上选出尽量少的点,使得和所有给出的n个点距离不超过D. 分别计算出每个点在线段的满足条件的区间,然后就转化成了区间选点的问题了,按照右端点排序,相同时按照左端点排序,按照之前的排序一定 ...

  9. python基础一 day15 面试题

    # def demo():# for i in range(4):# yield i## g=demo()## g1=(i for i in g)# g2=(i for i in g1)## prin ...

  10. 《队长说得队》【Alpha】Scrum meeting 4

    项目 内容 这个作业属于哪个课程 >>2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 >>实验十二 团队作业8:软件测试与ALPHA冲刺 团队名称 ...