《算法十》(动态规划)

动态规划:

  使用动态规划:重叠子问题

  最优值,最佳解

  斐波那契数列问题:如果递归解决需要重复算很多次fib(5)

        解决:使用一个数组把每次算过的存起来,下次再用直接调值

例题:

问题描述:

解答:

#include <iostream>
#include <iomanip> 
#include <math.h>
#include <string.h>
#define NUM 6 
using namespace std;

//递归 
bool isOk(int arr[], int i, int s){
	if( s==0 ){//如果要找的s是0,那么肯定OK 
		return true;
	}else if( i==0 ){//如果只剩下最后一个了,如果arr[0]==s的话OK,否则不成功 
		return arr[0]==s;
	}else if( arr[i]>s ){//如果当前的arr[i]的值超过要找的s,那么去掉它 
		return isOk(arr, i-1, s);
	}else{
		//2种选择:
		//第一种:选择当前值,那么相应s要去掉当前值,同时i-1 
		bool x = isOk(arr, i-1, s-arr[i]);
		//第二种:不选择当前值,那么直接i-1 
		bool y = isOk(arr, i-1, s);
		//2种选择任意一种成功就行 
		return (x||y);
	}
}

//非递归
bool feidigui(int arr[], int s){
	//构建辅助数组:
	//行等于arr数组的行,列代表s经过变化的可能取值(0~s:s+1个数) 
	bool arrTemp[NUM][s+1];
	 
	for(int i=0; i<NUM; i++){//第一列:s全部等于0,那么都是true 
		arrTemp[i][0] = true;
	}
	for(int i=0; i<s+1; i++){//第一行:只剩下一个值了,只有这个值和s相等才对,否则是false找不到 
		if( arr[0]==i )//这个值和s相等
			arrTemp[0][i] = true; 
		else//这个值和s不相等
			arrTemp[0][i] = false;
	}
	
	for(int i=1; i<NUM; i++){
		for(int j=1; j<s+1; j++){
			if(arr[i]>s){//如果当前的arr[i]的值超过要找的s,那么去掉它 
				arrTemp[i][j] = arrTemp[i-1][j];	
			}else{
				//选择当前值,那么相应j要去掉当前值,同时i-1 
				bool x = arrTemp[i-1][j-arr[i]];
				//不选择当前值,那么直接i-1  
				bool y = arrTemp[i-1][j];
				arrTemp[i][j] = (x or y);
			}
		}
	}
	return arrTemp[NUM-1][s];
} 

int main(void){
	int arr[] = {3, 34, 4, 12, 5, 2};
	
	if(isOk(arr, 5, 9)){
		cout << "true!" << endl;
	}else{
		cout << "false!" << endl;
	}
 	    
	if(feidigui(arr, 13)){
		cout << "true!" << endl;
	}else{
		cout << "false!" << endl;
	}	

	return 0;
} 

重点:

递归方法:找出递归出口+递归式

 非递归方法:构建一个二维数组,行存取0~5对应arr[i],列存取从0~s个值(一共s+1个数)

原文地址:https://www.cnblogs.com/Whgy/p/12299515.html