基础dp(2)补充
完全背包:
有N种物品和一个容量为V的背包,每种物品都有无限件可用。
根据01背包的状态转移方程我们可以得知:
dp(i,j)=max(dp(i-1,j),dp(i-1,j-v[i])+val[i])
这里因为01背包每种物品只有一件可用,所以只有选一个这个物品和不选这一个物品两个选择。如果这个物品数量变为无限个,那么就有不选这个物品、选一个这个物品、选两个、三个......k个这些可能。而这些可能可以用下一个状态dp(i,j-v)+w来表示
即dp(i,j-v)=max( dp(i-1,j-v) , dp(i-1,j-2v)+w,dp(i-1,j-3v)+2w , dp(i-1,j-4v)+3w......k , dp(i-1,j-kv)+(k-1)w) )。
所以我们得出完全背包的状态转移方程:dp(i,j)=max(dp(i-1,j),dp(i,j-v)+w)。
优化成一维之后为:dp[j]=max(dp[j],dp[j-v]+w)。
eg:https://www.luogu.com.cn/problem/P1616
代码:
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; long long a[10010],b[10010]; long long dp[10000010]; int main() { long long t,m; scanf("%lld %lld",&t,&m); for(int i=1;i<=m;i++){ scanf("%d %d",&a[i],&b[i]); } for(int i=1;i<=m;i++){ for(int j=a[i];j<=t;j++){ dp[j]=max(dp[j],dp[j-a[i]]+b[i]); } } printf("%lld\n",dp[t]); return 0; }
(注意long long)
EOF