【主要内容】
动态规划
背包类型的dp:01背包
线性dp:最长公共子序列,编辑距离
经典例题: 独立任务最优调度,最大子段和
01背包
【题目链接】
https://www.acwing.com/problem/content/2/
【题目描述】
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。
【数据范围】
0<N,V≤1000 0<vi,wi≤1000
【输入样例】
4 5
1 2
2 4
3 4
4 5
【输出样例】
8
【题解】 设 f[i][j]挑选前i个物品放入背包在容量为j时,获取的最大价值。
在挑选第i个物品时,当能放入的情况下,写出对应的状态转移方程:
即放入时,腾出对应的空间出来放物品,同时获取对应的价值。
最后相比较,在放与不放之间取最大值
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int N = 1e3 + 10 ; 5 int f[N][N] , v[N] , w[N] ; 6 int main() 7 { 8 int n , V ; 9 scanf("%d%d",&n,&V); 10 for( int i = 1 ; i <= n ; i++ ){ 11 scanf("%d%d",&v[i],&w[i]); 12 } 13 14 //枚举物品 15 for( int i = 1 ; i <= n ; i++ ){ 16 //枚举背包容量 17 for( int j = 0 ; j <= V ; j ++ ){ 18 //如果能承载该物品,基于前i-1个物品的情况后放入,若能比不放 的价值大则替换 19 if( j >= v[i] ){ 20 f[i][j] = max( f[i-1][j] , f[i-1][j-v[i]] + w[i] ); 21 } 22 //若不能放入,则维持原来的价值. 23 else{ 24 f[i][j] = f[i-1][j] ; 25 } 26 } 27 } 28 printf("%d\n",f[n][V]); 29 return 0; 30 }