여러 배낭 문제 (이진 최적화)

여러 배낭 문제

N 개의 아이템과 V 용량의 배낭이 있습니다.

i 번째 항목에는 최대 si 항목이 있으며, 각각의 볼륨은 vi이고 값은 wi입니다.

배낭에 어떤 아이템이 적재되었는지 확인하여 아이템의 총 부피가 배낭의 용량을 초과하지 않고 총 값이 가장 큽니다.
최대 값을 출력합니다.

입력 형식
공백으로 구분 된 두 정수 N, V 첫 번째 줄은 각각 개체 수와 배낭의 부피를 나타냅니다.

다음으로, 각각 공백으로 구분 된 세 개의 정수 vi, wi, si가있는 N 개의 행이 있으며, 이는 i 번째 항목의 볼륨, 값 및 수량을 나타냅니다.

출력 형식
최대 값을 나타내는 정수를 출력합니다.

데이터 범위
0 <
N≤1000 0 <V≤2000
0 <vi, wi, si≤2000
팁 :
이 질문은 여러 배낭의 이진 최적화 방법을 조사합니다.

입력 샘플
4 5
1 2 3
2 4 1
3 4 3
4 5 2
출력 샘플 :
10
이 데이터는 일반적인 다중 배낭 문제보다 훨씬 큽니다.
그래서 재치 나는 바이너리 최적화를 가지고 있습니다! ! !
먼저 코드를보세요
여러 개의 배낭을 01 개의 배낭으로 바꾸는 것

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
int n,m,s[10000],vv[10000],v[100000],ww[100000],w[100000],i,j,k,t,d[10000000];
int main()
{
    
    

	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
	scanf("%d%d%d",&vv[i],&ww[i],&s[i]);
	for(i=0;i<=m;i++)
	d[i]=0;
	k=1;
	for(i=1;i<=n;i++)
	{
    
    
		for(j=1;j<s[i];j*=2)//二进制优化过程
		{
    
    
			v[k]=j*vv[i],w[k]=j*ww[i];
			k++;
			s[i]-=j;
		}
		if(s[i])
		{
    
    
			v[k]=s[i]*vv[i],w[k]=s[i]*ww[i];
			k++;
		}

	}
 k=k-1;//多算的1
 //这个是看看优化后的
	//for(i=1;i<=k;i++)
	//printf("%d %d\n",v[i],w[i]);
	//01背包他又来了
	for(i=1;i<=k;i++)
	for(j=m;j>=v[i];j--)
	{
    
    
		d[j]=max(d[j],d[j-v[i]]+w[i]);
	}
	printf("%d\n",d[m]);
}

바이너리를 사용하는 이유는 무엇입니까? ?
자신을 깨달으십시오!

추천

출처blog.csdn.net/m0_46381590/article/details/111479870