第一次接触动态规划,感觉动态规划就是将现有的问题转化为子问题,关键是找到状态转移方程,中间结果要保存,一般有K个变量就用K维数组来保存结果。
01背包是比较经典的DP例题:
有n个重量和价值分别为w(i),v(i)的物品。从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中价值总和的最大值。
限制条件
1<=n<=100
1<=w(i),v(i)<=100
1<=W<=10000
状态转移方程: dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
dp[i][j]表示把i件物品放入容量为w的背包中的最大价值,则可以转化为关注第i件物品,如果放入第i件物品则dp[i][j]等于前i-1件物品放入容量为j-w[i]的背包中再加上第i件物品的价值;如果不放入第i件物品则dp[i][j]=dp[i-1][j]即把i-1件物品放入容量为j的背包中。此题解法很多,dp形式各种各样,但思想大同小异。
C++代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int a[100],b[100];
int n,w;
int dp[100][100];
int main() {
cin>>n>>w;
for(int i=0;i<n;i++){
cin>>a[i]>>b[i];
}
memset(dp,0, sizeof(dp));
for (int i = 0; i <n ; ++i) {
for (int j = 0; j <=w ; ++j) {
if (j<a[i]){
dp[i+1][j]=dp[i][j];
}else {
dp[i+1][j]=max(dp[i][j],dp[i][j-a[i]]+b[i]);
}
}
}
cout<<dp[n][w]<<endl;
}