CF-Tinkoff Challenge-Elimination Round-D-Presents in Bankopolis
2017-04-28 01:46
435 查看
ACM模版
典型的树归问题,从一个始发点不断查找下一个可行解,最后输出最小的可行解总和即可。
这么说是不是太随意了一些啊,毕竟我没有做出这道题。这个题并不算难,能想到动归就好办了。
首先我们设置一个 dp[st][ed][k] 表示从 st 点出发能到达的某个方向最远处 ed 点且剩余 k 个点未走,既然说到某一个方向,那么这里肯定是正向和反向,针对于正向和反向的不同还要有分别的状态转移方程,存图设置一个 mp[u][v],记住这里是有向图,搞成无向图会在第四组数据 WA,如果读得清楚题,自然知道是有向图,而我就是读不懂题的人。
设置完上边两个数组,剩下的也就是一个递归搜索,打个比方说,也就是如果从 st 在某一个方向最远可以到达 ed,那么这个区间中的任意一个都可以到达,假如此时到达了 mid,那么下一次分别是可以从 mid 到 st 和 mid 到 ed,这个具体不好说,还是看代码吧,一看就理解了,嘻嘻(^__^) 嘻嘻……
对了,考虑到边界问题,上述从 st 到达 ed 都是不包括 st 和 ed 的,也就是说 (st,ed) 开区间。
强大的树归!!!
描述
题解
没怎么做过树归问题,所以当做到这道题时不免有些懵逼。典型的树归问题,从一个始发点不断查找下一个可行解,最后输出最小的可行解总和即可。
这么说是不是太随意了一些啊,毕竟我没有做出这道题。这个题并不算难,能想到动归就好办了。
首先我们设置一个 dp[st][ed][k] 表示从 st 点出发能到达的某个方向最远处 ed 点且剩余 k 个点未走,既然说到某一个方向,那么这里肯定是正向和反向,针对于正向和反向的不同还要有分别的状态转移方程,存图设置一个 mp[u][v],记住这里是有向图,搞成无向图会在第四组数据 WA,如果读得清楚题,自然知道是有向图,而我就是读不懂题的人。
设置完上边两个数组,剩下的也就是一个递归搜索,打个比方说,也就是如果从 st 在某一个方向最远可以到达 ed,那么这个区间中的任意一个都可以到达,假如此时到达了 mid,那么下一次分别是可以从 mid 到 st 和 mid 到 ed,这个具体不好说,还是看代码吧,一看就理解了,嘻嘻(^__^) 嘻嘻……
对了,考虑到边界问题,上述从 st 到达 ed 都是不包括 st 和 ed 的,也就是说 (st,ed) 开区间。
强大的树归!!!
代码
#include <iostream> #include <cstring> #include <algorithm> #define POSTIVE 1 #define REBERSE 0 using 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; }
相关文章推荐
- Tinkoff Challenge - Elimination Round D. Presents in Bankopolis(区间DP)
- [平衡树 模拟] SnackDown 2017 Online Elimination Round #WIQ Waiting in a Queue
- Presents in Bankopolis CodeForces - 793D
- 【codeforces 793D】Presents in Bankopolis
- CF-Tinkoff Challenge-Elimination Round-A-Oleg and shares
- CF-Tinkoff Challenge-Elimination Round-B-Igor and his way to work
- Codeforces 793 D. Presents in Bankopolis
- CROC-MBTU 2012, Elimination Round / 245E Mishap in Club (想法题)
- CF-Tinkoff Challenge-Elimination Round-C-Mice problem
- CF--Technocup 2017 - Elimination Round 2(ABCDE)
- cf Educational Codeforces Round 6 C Pearls in a Row
- POJ1584-A Round Peg in a Ground Hole
- 8VC Venture Cup 2016 - Elimination Round E. Simple Skewness 暴力+二分
- 8VC Venture Cup 2016 - Elimination Round题解
- poj 1584 A Round Peg in a Ground Hole
- Technocup 2017 — Elimination Round 2 (and Codeforces Round 380) Editorial B. Spotlights
- Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C. Destroying Array 带权并查集
- 8VC Venture Cup 2016 - Elimination Round-A. Robot Sequence(模拟)
- 创建和使用范围(Creating and Using Ranges)CFString in Core Foundation
- BestCoder Round 38-1001 Four Inages Strategy