1. 程式人生 > >C++ 動態規劃 01揹包+ 最大字陣列和 +最短路徑 +斐波那契數列

C++ 動態規劃 01揹包+ 最大字陣列和 +最短路徑 +斐波那契數列

int max(int a,int b)
{
	return a>b?a:b;
}
/*
0 1 揹包
*/
int MaxValue()
{
    int Weight[5]={2,2,6,5,4};//物品的重量陣列    
    int Value[5]={6,3,5,4,6};//物品價值陣列
    int Total_Count = 5/*物品個數*/,
	Total_w = 10 /*揹包承重*/;
	int f[5][10]={0};
	
	for(int Cur_w =1;Cur_w <= Total_w;Cur_w++)//揹包重量
    {
		for(int i=0;i<Total_Count;i++)//物品個數
        {    
            {
				//這裡需要考慮Cur_w是否大於Weight
				if(Cur_w >= Weight[i])
				{
					if(i==0)//第一件物品
					{
						f[i][Cur_w-1] = Value[i];
					}
					else
					{
						f[i][Cur_w-1] = max(f[i-1][Cur_w-1-Weight[i]]+Value[i],f[i-1][Cur_w-1]);	
					}
				}
				else//當前揹包承重小於i物品的重量時
				{
					//同樣考慮第一件物品的情況
					if(i==0)
					{
						f[i][Cur_w-1] = 0;	
					}
					else
					{
						f[i][Cur_w-1] = f[i-1][Cur_w-1];	
					}								
				}
            } 
         }
    }
	return f[4][9];
}


/*
最大子陣列
*/
#include<vector>
using namespace std;
int MaxSubarray(int a[],int n)
{
	vector<int> dp(n);
	dp[0] = a[0];
	int maxSub =a[0];
	for(int i=1;i<n;i++)
	{
		dp[i] = max(dp[i-1]+a[i],a[i]);
		maxSub = max(dp[i],maxSub);//記錄每一次的字陣列和,並取到最大值
	}
	return maxSub;
}


/*
最短路徑
*/
int path[11][11] =
//終點	A	B1	B2	C1	C2	C3	C4	D1	D2	D3	E
/*起點*/
/*A*/{  0,	5,	3,	0, 	0,	0,	0,	0,	0,	0,	0,
/*B1*/	0,	0,	0,	1,	6,	3,	0,	0,	0,	0,	0,
/*B2*/	0,	0,	0,	0,	0,	8,	4,	0,	0,	0,	0,
/*C1*/	0,	0,	0,	0,	0,	0,	0,	5,	6,	0,	0,
/*C2*/	0,	0,	0,	0,	0,	0,	0,	5,	0,	0,	0,
/*C3*/	0,	0,	0,	0,	0,	0,	0,	0,	0,	8,	0,
/*C4*/	0,	0,	0,	0,	0,	0,	0,	0,	0,	3,	0,
/*D1*/	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	3,
/*D2*/	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	4,
/*D3*/	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	3,
/*E*/	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0};

int MinPath()
{
	int i,j;
	for(i=9;i>=0;i--)
	{
		vector<int> temp(11);
		for(j=10;j>=0;j--)
		{
		//用當前行中,除最後一列的所有數字,加上path[j][10],取最小 ,賦給path[i][11];		
			if(path[i][j] > 0 && j!=10)//此處需要判斷邊界條件
			{
				temp[j] = path[j][10]+path[i][j];				
			}
		}
		vector<int>::iterator it =temp.begin();
		int temp_minipath = 10000;//指定一個遠大於所有路徑之和的所有值
		for(;it!=temp.end();it++)
		{
			if(*it!=0)
			{
				temp_minipath = temp_minipath < *it?temp_minipath:*it;
			}		
		}
		if(temp_minipath != 10000)
			path[i][10] = temp_minipath;//求當前點到E的最小路徑	
	}
	return path[0][10];
}


/*
斐波那契數列
*/

int DpFiboArray(int n)
{
	static vector<int> dp(n+1);
	if(n==0 || n==1)
	{
		dp[n] = 1;
		return dp[n];
	}
	else
	{
		if(dp[n-1] == 0)
			dp[n-1] = DpFiboArray(n-1);	
		if(dp[n-2] == 0)
			dp[n-2] = DpFiboArray(n-2);
		dp[n] = dp[n-1]+dp[n-2];
	}
	return dp[n];
}

int FiboArray(int n)
{
	if(n==0 || n==1)
		return 1;
	else
		return FiboArray(n-1)+FiboArray(n-2);
}


int _tmain(int argc, _TCHAR* argv[])
{
	// 01揹包
	int result = MaxValue();

	//最大字陣列
	int a[10]={31,-41,59,26,-53,58,97,-93,-23,84};
	int maxsub =MaxSubarray(a,10);

	//最短路徑
	int minpath = MinPath();

	//斐波那契數列
	int FiboNum =DpFiboArray(20); 

	return 0;
}