依然参照 http://hawstein.com/posts/dp-novice-to-advanced.html
问题描述
无向图G有N个结点,它的边上带有正的权重值。你从结点1开始走,并且一开始的时候你身上带有M元钱。如果你经过结点i, 那么你就要花掉S[i]元(可以把这想象为收过路费)。如果你没有足够的钱, 就不能从那个结点经过。在这样的限制条件下,找到从结点1到结点N的最短路径。
文章的伪代码如下,但他好像没有防止回路的例子,这里设置了回路避免标志edge矩阵:
#include <stdio.h>
#define NumVertices 5 //无向图中的顶点数
#define Money 20 //身上的钱数
#define tooMuch 1000 //在此过程中,tooMuch可以作为无穷大
#define isVisted true //某个特定剩余多少钱的节点是否被访问过
//解决带限制条件的的动态规划问题
int main()
{
int Cost[NumVertices] = {4,15,3,2,6};
int Graph[NumVertices][NumVertices] = {{0,2,1,3,tooMuch},{2,0,tooMuch,tooMuch,10},{1,tooMuch,0,3,tooMuch},{3,tooMuch,3,0,6},{tooMuch,10,tooMuch,6,0}};
bool Edge[NumVertices][NumVertices]={false};
bool Visited[NumVertices][Money+1] = {false};
int pathLength[NumVertices][Money+1];
for(int outIndex=0;outIndex<NumVertices;outIndex++)
{
for (int innerIndex=0;innerIndex<=Money;innerIndex++)
{
pathLength[outIndex][innerIndex]=tooMuch;
}
}
pathLength[0][Money]=0;
int flag=false;
while (true)
{
int minal=tooMuch-1;
int k=-1,l=-1;
for (int outIndex=0;outIndex<NumVertices;outIndex++)
{
for (int innerIndex=0;innerIndex<=Money;innerIndex++)
{
if ((!Visited[outIndex][innerIndex]) && minal>pathLength[outIndex][innerIndex])
{
minal = pathLength[outIndex][innerIndex];
k = outIndex;
l = innerIndex;
Visited[outIndex][innerIndex]=true;
}
}
}
if (k==-1 && l==-1)
{
flag = true;
break;
}
for (int index=0;index<NumVertices;index++)
{
if (Graph[k][index]!=tooMuch && k!=index && l>Cost[index] && pathLength[index][l-Cost[index]]>pathLength[k][l]+Graph[k][index] && !Edge[index][k])
{
Edge[k][index]=true;
Edge[index][k]=true;
pathLength[index][l-Cost[index]] = pathLength[k][l]+Graph[k][index];
}
}
}
int minimal=tooMuch-1;
int positions;
//find minimal
for (int index=0;index<=Money;index++)
{
if (minimal>=pathLength[NumVertices-1][index])
{
positions=index;
minimal=pathLength[NumVertices-1][index];
}
}
printf("remain money %d\n",positions);
printf("path length is %d\n",pathLength[NumVertices-1][positions]);
getchar();
return 0;
}