複数のナップサック問題
N個のアイテムとVの容量を持つバックパックがあります。
i番目のアイテムには最大でsi個のアイテムがあり、各アイテムのボリュームはviで、値はwiです。
アイテムの総量がバックパックの容量を超えないように、どのアイテムがバックパックにロードされているかを解決し、合計値が最大になります。
最大値を出力します。
入力形式
スペースで区切られた2つの整数N、Vの最初の行は、それぞれオブジェクトの数とバックパックの体積を示します。
次に、N行があり、それぞれに3つの整数vi、wi、siがあり、スペースで区切られ、i番目のアイテムの量、値、および数量を示します。
出力形式
最大値を表す整数を出力します。
データ範囲
0 <
N≤10000<V≤20000
<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]);
}
なぜバイナリを使用するのですか??
気づきなさい!