您的位置:首页 > 运维架构

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) 开区间。

强大的树归!!!

代码

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  树归