动态规划示例五

依然参照 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值