题目:
题解:
和01背包基本完全一样。小局部最优的策略也是一样:是否选当前局部的最后一项。唯一的不同点在于物品是无线的导致在表示选择当前物品的状态写法发生了改变:由dp[i-1][j-w[i]]变为了dp[i][j-w[i]]因为这样能够表示最后一件物品选多件的情况。
#include <iostream>
using namespace std;
int main(){
int total,N;
int w[1005]={0},v[1005]={0};
cin>>total>>N;
int dp[1005][1005]={0};
for(int i=1;i<=N;i++)cin>>w[i]>>v[i];
for(int i=1;i<=N;i++){
for(int j=0;j<=total;j++){
dp[i][j]=dp[i-1][j];
if(j>=w[i])dp[i][j]=max(dp[i][j],dp[i][j-w[i]]+v[i]);
}
}
cout<<dp[N][total];
return 0;
}
题后反思:
至于为什么j可以从1开始也可以从0开始我认为这其中因该包含了某种思想,现在我的答案是:
j为0和1的这些情况都小于了物品最的最小重量都只能从i-1得来所以都是0。
但其实这类题目的关键就在于思考清楚通过已有的值(入门后叫做状态)操作得出小局部最优的策略,然后注意初始值的设置递推得出答案即可。