가방 문제 의 01 가방
2700 단어 알고리즘
01 가방 은 가방 시리즈 의 기초 로 문 제 를 해결 하 는 사상 이 중요 하 다.01 가방 문 제 는 각 아 이 템 의 개 수 를 1 로 제한 합 니 다. 아 이 템 의 총 수량 N 과 한정 비용 V 를 알 기 시 작 했 습 니 다. 이어서 우 리 는 아 이 템 의 가치 val [i] 와 비용 vei [i] 를 얻 을 수 있 습 니 다.처음에 01 가방 을 접 했 을 때 자신 은 항상 욕심 을 떠 올 렸 다. 성 가 에 따라 높 은 것 에서 낮은 것 으로 순 서 를 매 긴 다음 에 앞의 몇 가지 물건 의 가 치 를 더 하면 된다.(실제 아 이 템 의 일 부 를 넣 을 수 있 는 가방 문 제 는 욕심 전략 으로 만 들 수 있 지만 01 가방 은 넣 거나 놓 지 않 는 문제 에 속 하기 때문에 DP 로 만 들 기 에 적합 합 니 다. 더 자세 한 분석 을 참고 하 시기 바 랍 니 다.http://blog.csdn.net/hy6688_/article/details/15427943) 그러나 이런 사고방식 은 엄밀 하지 않다. 예 를 들 어:
N=5 V=18
wei: 14 12 2 3 4
val: 28 24 3 4 5
val/wei: 2 2 1.5 1.3 1.25
이렇게 얻 은 결 과 는 28 로 31 이 최대 치 였 다.
N=3 V=18
wei:16 15 3
val:32 29 5
결 과 는 32, 진실 치 는 34.
욕심 을 부 리 는 사고방식 으로 하면 반드시 각 단계 에서 비용 V 가 충분 한 지 판단 해 야 한다. 설령 어느 단계 에 현재 의 물품 을 '자루' 에 넣 을 수 있다 하 더 라 도그러면 뒤의 더 좋 은 해석 을 차단 할 수도 있 습 니 다. 01 가방 문 제 를 해결 하 는 데 이렇게 중요 한 중간 분석 과정 이 있 습 니 다. i 번 째 물건 을 넣 거나 넣 지 않 는 것 은 원래 의 값 보다 크 거나 작 거나 가상 가방 이 많 습 니 다. i 번 째 물건 을 넣 을 수 있 는 가방 의 용량 은 V - wei [i] 입 니 다.모든 가방 을 시험 적 으로 놓 고 모든 아 이 템 에 대해 이러한 조작 을 하면 결 과 를 얻 을 수 있 습 니 다 Val [V]. 상태 이동 방정식: f [i] [w] = max (f [i - 1] [w - wei] + val [i], f [i - 1] [w]) 를 1 차원 배열 형식 으로 최적화 합 니 다: for (i = 1 - > N)
for(j=V-->wei[i])
Val[j]=max(Val[j-wei[i]]+val[i],Val[j]);
가방 (공간 이 다 되 었 습 니 다) 을 채 우 는 최 적 화 를 요구 하면 val [0] = 0 을 초기 화 합 니 다. 다른 모든 Val 은 - 0x3f3f3f3f3f3f (마이너스 무한) 입 니 다.
만약 에 공간 이 충분 한 상황 에서 가장 좋 은 해 를 요구한다 면 모든 Val 을 0 으로 초기 화 합 니 다. [한 물건 도 놓 지 않 으 면 가 치 는 당연히 0 입 니 다].
예:
항 저 우의 간단 한 01 가방 문제:http://acm.hdu.edu.cn/showproblem.php?pid=2602
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int wei[1005],val[1005],Val[1005];
int zerone(int val[],int wei[],int N,int V){
int i,j;
memset(Val,0,sizeof(Val));
for(i=0;i<N;i++){
for(j=V;j>=wei[i];j--){ //
int tmp=Val[j-wei[i]]+val[i];
Val[j]=tmp>Val[j]?tmp:Val[j];
}
//for(j=1;j<=V;j++)cout<<Val[j]<<" "; cout<<endl;
}
return Val[V];
}
int main(int argc, char *argv[]) {
//freopen("cin.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--){
int N,V,i;
scanf("%d%d",&N,&V);
for(i=0;i<N;i++)scanf("%d",&val[i]);
for(i=0;i<N;i++)scanf("%d",&wei[i]);
int ans=zerone(val,wei,N,V);
printf("%d
",ans);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Codility Lesson3】FrogJmpA small frog wants to get to the other side of the road. The frog is currently located at position X and wants to get to...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.