//poj1062 DP解法 三维DP,不用dij,不到30行代码,吓死我了
//d[i][j][k]代表得到第I个物品的最小花费 等级范围限制在j和k之间。j和k的范围随着交易变小
//j是最低范围,k是最大范围(没有考虑m的情况下)代表旅行家交易过的最低等级和最高等级。
//第一个点单枪匹马,通过递归不停更新自己的最小值。
//这份代码最为厉害,其他的代码,比如小优的代码,我看了一下,不是使用区间,而是直接暴力枚举所有的等级,
//每次只允许等级低的不超过当前点等级的点进行下一次访问。这个暴力,的确可以得到全部可能性。只是。。。
//很多人都是用dijkstra解决的, 思路是不断选择可选择的最短路,然后更新这个最短路源点的距离值。即
//存在A > B + C, A = B + C,使之满足整个dist矩阵,重复N次操作即可。
#include<iostream>
using namespace std;
#define min(a, b) (a < b?(a):(b))
int m, n, p[105], l[105], w[105][105], d[105][105][105];
int dfs(int x, int y, int z)
{
if(d[x][y][z])
return d[x][y][z];
d[x][y][z] = p[x];
for(int i = 1; i <= n; i++)
{
//l[i]必须小于y+m 大于z-m y逐渐变小,z逐渐变大,因此随着交易,区间范围变小
if(w[x][i] && m + y >= l[i] && z - m <= l[i])
{
d[x][y][z] = min(d[x][y][z], w[x][i] + dfs(i, (l[i]>y)?y:l[i], l[i]>z?l[i]:z));
}
}
return d[x][y][z];
}
int main()
{
int j, k, x;
cin>>m>>n;
for(int i = 1; i <= n; i++)
{
cin>>p[i]>>l[i]>>x;
while(x--)
{
cin>>j>>k;
w[i][j] = k;
}
}
cout<<dfs(1, l[1], l[1])<<endl;
return 0;
}
poj1062
最新推荐文章于 2020-02-28 17:13:33 发布