데이터 구조 및 알고리즘 - 동적 계획 기사

동적 프로그래밍 (동적 프로그래밍)

개념

큰 복잡한 문제는 작은 문제를 해결하여 큰 문제의 해결에 도달하기 위해, 간단한 작은 문제로 나눌 수 있습니다.

재산

아니 후 효과 : 이전 단계의이 단계에서 상태에 영향없이 개발이 단계 이후 상태 판정의 특정 단계, 후. 그 미래는 과거와는 아무 상관이 없습니다

최적의 하부 구조는 : 최적의 솔루션은 큰 문제가 작은 문제의 최적의 솔루션을 시작할 수 있습니다

중복 하위 문제 : 하향식 재귀 알고리즘 솔루션, 각 하위 문제는 항상 새로운 문제가 발생하지 않을 때, 일부 하위 문제가 반복된다.

범위

중복 하위 문제 및 최적의 하부 등록 문제

차이점은 분할 정복 및 동적 프로그래밍

공통 것은 : 모두 원래의 문제가 차선의 구조적 특성을 갖는다 필요 다음 원래 소규모의 개수로 나누어 분할 통치의 문제점 (작은 프로그램을 용이하게 해결하는) 하위 문제 및 하위 문제에 결합 된 솔루션이다. 원래 문제의 해결책을 형성한다.

다른 점 : 분할 정복 방법 하위 문제 재귀 DO를 이용하여, 서로 독립적으로 분해.

    분해 동적 프로그래밍 서브 문제는 서로 겹치는 부분에 접촉하도록 이해 일반적 반복 DO를 기억할 필요가있다.

단계

  • 추상 문제
  • 모델링 (궁극적으로 필요한 것)
  • 제약 (충족 조건의 종류)
  • 최적의 하부 구조를 가지고 결정
  • 정의 상태
  • 큰 문제와 작은 문제 상태 전이 방정식
  • 충전재
  • 결과 테이블에 따른 조성물의 솔루션을 추구하려면

질문 1 : 0-1 배낭 문제

n 개의 항목은 어떻게 배낭에 항목 합계의 최대 값을 가지고 있는지 확인하기 위해, 모자 배낭 할 수있는 능력 부여, 그들은 자신의 크기와 가치가있다?

분석 단계

추상적 인 문제는 각 항목에 대해 수행 할 가능성이 있거나 그렇게 사용 (X1, X2는, ... 사이에는, ..., Xn에)이 있거나없는하는 i 번째 항목을 나타낸다. 각 항목의 값을 바이, 무선 등의 각 항목의 크기이다.

모델링 : 가치를 극대화합니다. 맥스 (SUM (* 사이 Ⅵ)).

제약 : 합계 (사이 무선 *) <캡

최적 하부 : i는 현재 단계의 전체 최대 값을 만들 수 있다면, 각 스테이지는 항목의 조합으로 표현 될 수 있기 전에, 다른 단계에서 문제가 적용된다.

상태가 정의된다 : V (I, J) - 전 i 번째 문서 최상의 조합 합계치, 난 - 잔존 용량을 나타내는 j-- i 번째 이전 문서를 나타내고

상태 전이 방정식 : - 수 여부하는 i 번째 기사는 두 가지 선택이있다. 에 - 최대의 반드시 현재 총 가치 것은, 금지 - 최대 값은 이전 단계의 총 가치와 동일합니다.

조건을 분석하는 단계 - 배낭의 잔여 용량을 초과 할 수 없다.

V (I, J) = V (I -1, j)는, 무선> J -되지 i 번째 항목

V (I, J) = {V 맥스 (I -1, J - 무선) + 바이, V (i가 J, -1)}, WI <J = - i 번째 항목

static int[][] findMax(int cap, int n, int[] value, int[] weight, int[] item){
		int[][] v = new int[n + 1][cap + 1]; //建立路由表
		//首先初始化第一列第一行
		for (int i = 0; i < v.length; i++) {
			v[i][0] = 0;
		}
		for (int i = 0; i < v[0].length; i++) {
			v[0][i] = 0;
		}
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= cap; j++) {
				if(weight[i - 1] > j) {  //大小和价值数组均要减1才能不越界
					v[i][j] = v[i - 1][j];
				}else {
					if(v[i - 1][j] < (v[i - 1][j - weight[i - 1]] + value[i - 1])) {
						v[i][j] = v[i - 1][j - weight[i - 1]] + value[i - 1];	
					}	
					else { 
						v[i][j] = v[i - 1][j];	
					}
				}
			}
		}
		return v;
}
public static void main(String[] args) {
		int n = 4;
		int cap = 8;
		int[] value = new int[n];
		int[] weight = new int[n];
		System.out.println("请输入每个物品的价值:");
		for(int i = 0; i < n; i++) {
			Scanner in = new Scanner(System.in);
			if(in.hasNextInt())
				value[i] = in.nextInt();
		}
		System.out.println("请输入每个物品的大小:");
		for(int i = 0; i < n; i++) {
			Scanner in = new Scanner(System.in);
			weight[i] = in.nextInt();
		}
		int[] item = new int[n];
		int[][] res = findMax(cap, n, value, weight,item);
		System.out.println(res[n][cap]);
}

 

 

참조 :

https://www.cnblogs.com/raichen/p/5772056.html

https://www.zhihu.com/question/23995189/answer/613096905

https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html

추천

출처blog.csdn.net/qq_40722284/article/details/92016493