0-1揹包優化動態規劃演算法之跳躍點法
阿新 • • 發佈:2019-01-11
// 動態規劃 揹包問題 跳躍點優化
#include <iostream>
using namespace std;
template<class Type>
void Traceback(int n,Type w[],Type v[],Type **p,int *head,int x[])
{
Type j = p[head[0]-1][0],m=p[head[0]-1][1];
for(int i=1; i<=n; i++)
{
x[i]=0;
for(int k=head[i+1]; k<=head[i]-1 ; k++)
{
if(p[k][0]+w[i]==j && p[k][1]+v[i]==m)
{
x[i]=1;
j=p[k][0];
m=p[k][1];
break;
}
}
}
}
template<class Type>
int Knapsack(int n,Type c,Type v[],Type w[],int **p,int x[])
{
int *head = new int[n+2];
head[n+1]=0;
p[0][0]=0;
p[0][1]=0;
int left = 0,right = 0,next = 1;
head[n]=1;
for(int i=n; i>=1; i--)
{
int k = left;
for(int j=left; j<=right; j++)
{
if(p[j][0]+w[i]>c) break;
Type y = p[j][0 ] + w[i],m = p[j][1] + v[i];
while(k<=right && p[k][0]<y)
{
p[next][0]=p[k][0];
p[next++][1]=p[k++][1];
}
if(k<=right && p[k][0]==y)
{
if(m<p[k][1])
{
m=p[k][1];
}
k++;
}
if(m>p[next-1][1])
{
p[next][0]=y;
p[next++][1]=m;
}
while(k<=right && p[k][1]<=p[next-1][1])
{
k++;
}
}
while(k<=right)
{
p[next][0]=p[k][0];
p[next++][1]=p[k++][1];
}
left = right + 1;
right = next - 1;
head[i-1] = next;
}
Traceback(n,w,v,p,head,x);
return p[next-1][1];
}
int main()
{
int c;
cout<<"請輸入待裝物品的數量: "<<endl;
int N;
cin>>N;
int w[N+1];
int v[N+1];
cout<<"請輸入各個物品的重量及其對應價值:"<<endl;
for(int i=1; i<=N; i++)
{
cin>>w[i];
cin>>v[i];
}
int x[N+1];
cout<<"請輸入揹包最大載重量:"<<endl;
cin>>c;
int **p = new int *[50];
for(int i=0; i<50; i++)
{
p[i] = new int[2];
}
cout<<"揹包能裝的最大價值為:"<<Knapsack(N,c,v,w,p,x)<<endl;
cout<<"揹包裝下的物品編號為:"<<endl;
for(int i=1; i<=N; i++)
{
if(x[i]==1)
{
cout<<i<<" ";
}
}
cout<<endl;
for(int i=0; i<50; i++)
{
delete p[i];
}
delete[] p;
return 0;
}