動的計画法による01リュックの問題解決(C++実現)
質問説明:所定のn種類の商品と所定の固定容量のリュックサック.品物iの重さはW[i]で、価値はV[i]で、リュックサックの容量はCです.リュックサックに入ったものの総価値が最大になるように、リュックサックに入ったものをどのように選択すればいいですか?
(同じものについては、置くか置かないか、リュックサックに何度も入れることができず、分割して部分的に入れることもできないため、この問題を0-1リュックサック問題と呼ぶ)
(同じものについては、置くか置かないか、リュックサックに何度も入れることができず、分割して部分的に入れることもできないため、この問題を0-1リュックサック問題と呼ぶ)
#include
#include
#include
using namespace std;
int tableTwo[10][100];
int flag[10] = {
-1 };
// n->1 。 ,
int KnapsackTwo(vector<int> v, vector<int> w, int c, int n) {
int jMax = min(w[n] - 1, c);
for (int j = 0; j<jMax; j++)
tableTwo[n][j] = 0; //j
for (int j = w[n]; j <= c; j++)
tableTwo[n][j] = v[n]; // , tableTwo[n][j]=v[n];
for (int i = n - 1; i>1; i--) {
jMax = min(w[i], c);
for (int j = 0; j <= jMax; j++)
tableTwo[i][j] = tableTwo[i + 1][j];
for (int j = w[i]; j <= c; j++)
tableTwo[i][j] = max(tableTwo[i + 1][j], tableTwo[i + 1][j - w[i]] + v[i]);// , ,
}
tableTwo[1][c] = tableTwo[2][c];// 1
if (c >= w[1])tableTwo[1][c] = max(tableTwo[1][c], tableTwo[2][c - w[1]] + v[1]);//
return tableTwo[1][c];//
}
void Traceback(vector<int> w, int c, int n) {
// ,
for (int i = 1; i<n; i++) {
if (tableTwo[i][c] == tableTwo[i + 1][c])flag[i] = 0;
else {
flag[i] = 1;
c -= w[i];
}
}
flag[n] = tableTwo[n][c] ? 1 : 0;
}
int main()
{
int num;//
int sum;//
cout<<" "<<endl;
cin >> num >> sum;
vector<int> weight;//
vector<int> price;//
cout << " :";
weight.push_back(0);
price.push_back(0);
for (int i = 0; i < num; i++)
{
int tmp1;
cin >> tmp1;
weight.push_back(tmp1); //
}
cout << endl;
cout << " :";
for (int i = 0; i < num; i++)
{
int tmp2;
cin >> tmp2;
price.push_back(tmp2) //
}
cout << endl;
cout << " :" << KnapsackTwo(price, weight, sum, num) << endl;
Traceback(weight, sum, num);
cout << " :";
for (int i = 1; i<num + 1; i++)cout << flag[i] << " ";
cout << endl;
system("pause");
return 0;
}