01揹包問題
一維數組優化
for(int i=1;i<=n;i++)
for(int c=m;c>=0;c--)
if(c>=w[i])
f[c]=max(f[c],f[c-w[i]]+v[i]);
常數優化
for(int i=1;i<=n;i++)
{
sumw+=w[i];
bound=max(m-sumw,w[i]);
for(int c=m;c>=bound;c--)
if(c>=w[i])
f[c]=max(f[c],f[c-w[i]]+v[i]);
}
完全揹包問題 (每個物品無數件)
for(int i=1;i<=n;i++)
for(int c=0;c<=m;c++)
if(c>=w[i])
f[c]=max(f[c],f[c-w[i]]+v[i]);
多重揹包問題 (每件物品最多有**件可用)
for(int i=1;i<=n;i++)
{
if(w[i]*a[i]>m)
for(int c=0;c<=m;c++)
if(c>=w[i])
f[c]=max(f[c],f[c-w[i]]+v[i]);
else
{
k=1;amount=a[i];
while(k<amount)
{
for(int c=k*w[i];c>=0;c--)
if(c>=w[i])
f[c]=max(f[c],f[c-w[i]]+k*v[i]);
amount-=k;
k<<=1;
}
for(int c=amount*w[i];c>=0;c--)
f[c]=max(f[c],f[c-w[i]]+amount*v[i]);
}
}
泛化物品 (一個定義域爲0..v中的整數的函數h,當分配給它的費用爲v時,能得到的價值就是h(v))
long long qpow(int i,int b)
{
long long ans=1;
long long base=i,times=1;
while(times<=b)
{
if(times&b)
{
ans*=base;
}
base*=base;
times<<=1;
}
return ans;
}
int v,n;
long long dp[maxn],t[maxn][maxn];
void init()
{
v=read();
n=read();
memset(dp,10,sizeof dp);
dp[0]=0;
for(int k=1;k<=n;k++)
{
int a=read();
int b=read();
for(int i=1;i<=v;i++)
t[k][i]=a*qpow(i,b);
}//預處理所有的情況
}
void DP()
{
for(int i=1;i<=n;i++)
for(int j=v;j>=0;--j)
for(int k=1;k<=j;k++)
dp[j]=min(dp[j],dp[j-k]+t[i][k]);//01揹包
}