題目連結:戳這裡
題目大意:n個物品,每個物品有a和b兩個屬性,現在要選一些物品,使得a屬性的和是b屬性的和的k倍,求a屬性和的最大值。
題解:将問題變形:将每個物品的重量看做a[i]-k*b[i],價值看做a[i],分正負做兩次背包,最終兩個重量相等的背包就是一組可行解。
代碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int read()
{
char c;int sum=0,f=1;c=getchar();
while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){sum=sum*10+c-'0';c=getchar();}
return sum*f;
}
int n,k,ans=-1;
int a[105],b[105],c[105];
int dp1[10005],dp2[10005];
int main()
{
n=read();k=read();
for(int i=1;i<=n;i++)
a[i]=read();
for(int i=1;i<=n;i++)
b[i]=read(),c[i]=a[i]-b[i]*k;
memset(dp1,-0x3f,sizeof(dp1));
memset(dp2,-0x3f,sizeof(dp2));
dp1[0]=dp2[0]=0;
for(int i=1;i<=n;i++)
{
if(c[i]>=0)
{
for(int j=10000;j>=c[i];j--)
dp1[j]=max(dp1[j],dp1[j-c[i]]+a[i]);
}
else
{
c[i]=-c[i];
for(int j=10000;j>=c[i];j--)
dp2[j]=max(dp2[j],dp2[j-c[i]]+a[i]);
}
}
for(int i=0;i<=10000;i++)
{
if(!dp1[i] && !dp2[i]) continue;
else ans=max(ans,dp1[i]+dp2[i]);
}
printf("%d\n",ans);
return 0;
}