白俊#12865.平凡なリュック
9458 ワード
白俊#12865。平凡なリュック
整理する
動的プログラミングアルゴリズムの問題では、メモ帳テクノロジーを使用するときに「どのようなメモリ(値)を格納するか」という問題がよく発生します.
このようなバックパック問題では、物を入れることができる総バックパック容量が限られているため、「バックパック容量」は注釈で考慮しなければならない.
iii 3つ目のものを入れる場合、リュック容量(耐えられる重量)がjjjの場合、リュックに入れることができるものの価値の和の最低価格はdp(i,j)dp(i,j)dp(i,j)dp(i,j)であり、この問題を解決できる点火式は以下の通りである.
dp(i, j)={max{dp(i−1, j), V(i) + dp(i−1, j−W(i))}if j−W(i)≥0,dp(i−1, j)if j−W(i)≤0.dp(i,~j) =\begin{cases} max\{dp(i-1,~j),~V(i)~+~dp(i-1,~j-W(i))\} &\text{if }~j-W(i)\geq0,\\dp(i-1,~j) &\text{if } ~j-W(i)\leq0.\end{cases}dp(i, j)={max{dp(i−1, j), V(i) + dp(i−1, j−W(i))}dp(i−1, j)if j−W(i)≥0,if j−W(i)≤0.
(W(i)W(i)W(i)W(i)は3番目のものの重量を表し、V(i)V(i)V(i)は3番目のものの価値を表す.)
この点画式は次の解答コードのコメントと一緒に参考にすればいいです.
正しいコード
#include <iostream>
#include <algorithm>
using namespace std;
int main(void) {
int N, K;
int W[101];
int V[101];
int dp[101][100001];
// dp 2차원 배열의 바깥쪽은 i번째 물건일 때, 안쪽은 버틸 수 있는 무게가 j일 때의 값을 저장한다.
cin>>N>>K;
for (int i=1; i<=N; i++) {
cin>>W[i]>>V[i];
}
// default 값 설정. 0번째 물건은 존재하지 않으므로 0으로 초기화.
for(int i=0; i<=K; i++) {
dp[0][i] = 0;
}
// default 값 설정. 배낭의 용량이 0이면 아무것도 넣을 수 없으므로 0으로 초기화.
for(int i=0; i<=N; i++) {
dp[i][0] = 0;
}
// 배낭의 용량이 j라고 할 때, i번째 물건을 넣을 수 있을까?
for(int i=1; i<=N; i++) {
for(int j=1; j<=K; j++) {
if (j - W[i] < 0) {
// i번째 물건의 무게가 j보다 커서 넣을 수 없을 때
dp[i][j] = dp[i-1][j];
}
else {
// 무게가 j보다 작다면 가능한 두 가지 case 중 최댓값을 넣어준다.
// 1. i번째 물건을 넣지 않은 경우
// 2. i번째 물건을 넣는 경우 (이때는, i-1번째까지 넣었을 때, 남은 용량이 W[i]만큼은 확보되어 있어야 한다.)
dp[i][j] = max(dp[i-1][j], V[i] + dp[i-1][j-W[i]]);
}
}
}
cout<<dp[N][K]<<endl;
return 0;
}
Reference
この問題について(白俊#12865.平凡なリュック), 我々は、より多くの情報をここで見つけました https://velog.io/@chnh506/백준-12865-평범한-배낭テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol