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背包
}