동적 프로그래밍 (동적 프로그래밍)
개념
큰 복잡한 문제는 작은 문제를 해결하여 큰 문제의 해결에 도달하기 위해, 간단한 작은 문제로 나눌 수 있습니다.
재산
아니 후 효과 : 이전 단계의이 단계에서 상태에 영향없이 개발이 단계 이후 상태 판정의 특정 단계, 후. 그 미래는 과거와는 아무 상관이 없습니다
최적의 하부 구조는 : 최적의 솔루션은 큰 문제가 작은 문제의 최적의 솔루션을 시작할 수 있습니다
중복 하위 문제 : 하향식 재귀 알고리즘 솔루션, 각 하위 문제는 항상 새로운 문제가 발생하지 않을 때, 일부 하위 문제가 반복된다.
범위
중복 하위 문제 및 최적의 하부 등록 문제
차이점은 분할 정복 및 동적 프로그래밍
공통 것은 : 모두 원래의 문제가 차선의 구조적 특성을 갖는다 필요 다음 원래 소규모의 개수로 나누어 분할 통치의 문제점 (작은 프로그램을 용이하게 해결하는) 하위 문제 및 하위 문제에 결합 된 솔루션이다. 원래 문제의 해결책을 형성한다.
다른 점 : 분할 정복 방법 하위 문제 재귀 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