树形DP 【codeforces 793D】Presents in Bankopolis
来源:互联网 发布:罗宇回忆录 知乎 编辑:程序博客网 时间:2024/06/05 19:37
传送门
判断是否是一道树规题:
即判断数据结构是否是一棵树,然后是否符合动态规划的要求。如果是,那么执行以下步骤,如果不是,那么换台。
建树:通过数据量和题目要求,选择合适的树的存储方式。
如果节点数小于5000,那么我们可以用邻接矩阵存储,如果更大可以用邻接表来存储(注意边要开到2*n,因为是双向的。这是血与泪的教训)。如果是二叉树或者是需要多叉转二叉,那么我们可以用两个一维数组brother[],child[]来存储(这一点下面会仔细数的)。
写出树规方程:通过观察孩子和父亲之间的关系建立方程。我们通常认为,树形DP的写法有两种:a.根到叶子: 不过这种动态规划在实际的问题中运用的不多。本文只有最后一题提到。
b.叶子到根: 既根的子节点传递有用的信息给根,完后根得出最优解的过程。这类的习题比较的多。
Bankopolis is an incredible city in which all the n crossroads are located on a straight line and numbered from 1 to n along it. On each crossroad there is a bank office.
The crossroads are connected with m oriented bicycle lanes (the i-th lane goes from crossroad ui to crossroad vi), the difficulty of each of the lanes is known.
Oleg the bank client wants to gift happiness and joy to the bank employees. He wants to visit exactly k offices, in each of them he wants to gift presents to the employees.
The problem is that Oleg don't want to see the reaction on his gifts, so he can't use a bicycle lane which passes near the office in which he has already presented his gifts (formally, the i-th lane passes near the office on the x-th crossroad if and only if min(ui, vi) < x < max(ui, vi))). Of course, in each of the offices Oleg can present gifts exactly once. Oleg is going to use exactly k - 1bicycle lane to move between offices. Oleg can start his path from any office and finish it in any office.
Oleg wants to choose such a path among possible ones that the total difficulty of the lanes he will use is minimum possible. Find this minimum possible total difficulty.
The first line contains two integers n and k (1 ≤ n, k ≤ 80) — the number of crossroads (and offices) and the number of offices Oleg wants to visit.
The second line contains single integer m (0 ≤ m ≤ 2000) — the number of bicycle lanes in Bankopolis.
The next m lines contain information about the lanes.
The i-th of these lines contains three integers ui, vi and ci (1 ≤ ui, vi ≤ n, 1 ≤ ci ≤ 1000), denoting the crossroads connected by the i-th road and its difficulty.
In the only line print the minimum possible total difficulty of the lanes in a valid path, or -1 if there are no valid paths.
7 441 6 26 2 22 4 22 7 1
6
4 342 1 21 3 23 4 24 1 1
3
In the first example Oleg visiting banks by path 1 → 6 → 2 → 4.
Path 1 → 6 → 2 → 7 with smaller difficulity is incorrect because crossroad 2 → 7 passes near already visited office on the crossroad 6.
In the second example Oleg can visit banks by path 4 → 1 → 3.
【题意】
给你n个点,
这n个点
从左到右1..n依序排;
然后给你m条有向边;
然后让你从中选出k个点.
这k个点形成的一条路径;
且在路径中,一个被访问过的点不会经过两次或以上;
比如从1->3(1和3被访问过)
然后再从3->4(1,3,4都被访问过)
再从4->2(这时会又经过3号节点,而3号节点之前被访问过,所以不合法)
这就不是合法的;
首先我们设置一个 dp[st][ed][k] 表示从 st 点出发能到达的某个方向最远处 ed 点且剩余 k 个点未走,既然说到某一个方向,那么这里肯定是正向和反向,针对于正向和反向的不同还要有分别的状态转移方程,存图设置一个 mp[u][v],记住这里是有向图,搞成无向图会在第四组数据 WA,
设置完上边两个数组,剩下的也就是一个递归搜索,打个比方说,也就是如果从 st 在某一个方向最远可以到达 ed,那么这个区间中的任意一个都可以到达,假如此时到达了 mid,那么下一次分别是可以从 mid 到 st 和 mid 到 ed。
等于左右都走一边
#include <iostream>#include <cstring>#include <algorithm>#include <stdio.h>#define POSTIVE 1#define REBERSE 0using namespace std;const int MAXN = 88;const int INF = 0x3f3f3f3f;int dp[MAXN][MAXN][MAXN];int mp[MAXN][MAXN];int n, k, m;int u, v, c;void init(){ memset(dp, -1, sizeof(dp)); memset(mp, 0x3f, sizeof(mp));}int getDP(int st, int ed, int k, int dir){ if (dp[st][ed][k] != -1) { return dp[st][ed][k]; } if (k == 0) { dp[st][ed][k] = 0; return dp[st][ed][k]; } int res = INF; if (dir) { for (int i = st + 1; i < ed; i++) { if (mp[st][i] != INF) { res = min(res, mp[st][i] + getDP(i, st, k - 1, REBERSE)); res = min(res, mp[st][i] + getDP(i, ed, k - 1, POSTIVE)); } } } else { for (int i = ed + 1; i < st; i++) { if (mp[st][i] != INF) { res = min(res, mp[st][i] + getDP(i, st, k - 1, POSTIVE)); res = min(res, mp[st][i] + getDP(i, ed, k - 1, REBERSE)); } } } dp[st][ed][k] = res; return dp[st][ed][k];}int main(int argc, const char * argv[]){// freopen("/Users/zyj/Desktop/input.txt", "r", stdin); init(); scanf("%d%d%d", &n, &k, &m); for (int i = 1; i <= m; i++) { scanf("%d%d%d", &u, &v, &c); mp[u][v] = min(mp[u][v], c); // 可能会有重边,重边只保留最短边 } int res = INF; for (int i = 1; i <= n; i++) // 以任何一个点为起点 { res = min(res, getDP(i, 0, k - 1, REBERSE)); res = min(res, getDP(i, n + 1, k - 1, POSTIVE)); } if (res == INF) { cout << "-1\n"; } else { cout << res << '\n'; } return 0;}
- 树形DP 【codeforces 793D】Presents in Bankopolis
- Codeforces 793D Presents in Bankopolis DP
- Codeforces 793D Presents in Bankopolis【Dp+记忆化搜索】
- Codeforces 793 D. Presents in Bankopolis
- 793D Presents in Bankopolis
- Presents in Bankopolis CodeForces
- CF 793D Presents in Bankopolis
- CF-Tinkoff Challenge-Elimination Round-D-Presents in Bankopolis
- codeforces 161D D. Distance in Tree(树形dp)
- codeforces 161D Distance in Tree(树形dp)
- CodeForces 160D - Distance in Tree 树形DP
- codeforces 161D - Distance in Tree(树形dp)
- CodeForces 161D Distance in Tree(树形DP)
- codeforces 161D Distance in Tree (树形DP 经典题)
- CodeForces 161D Distance in Tree 树形DP
- Codeforces 161 D Distance in Tree 树形DP
- Codeforces 814D An overnight dance in discotheque DP(树形)
- Codeforces 161D 树形DP
- 侧面导航栏,bootstrap+jquery,收放功能
- 含有“static”的代码执行顺序!!!
- Apache+Tomcat实现负载均衡及集群(session同步)--二、环境准备(2)
- transitionend animationend 事件兼容问题
- 新博客
- 树形DP 【codeforces 793D】Presents in Bankopolis
- Android Studio 3.0 开发AndroidInstantApps(免安装应用)
- [机器学习]03.高级优化法(Advanced Optimization)
- tomcat配置文件server.xml详解
- 文章标题
- dovecot
- USACO-Section1.2 Transformations【数论.矩阵旋转】
- Apache+Tomcat实现负载均衡及集群(session同步)--二、环境准备(3)
- java复习—— static static final 关键字的使用方式