思路:
跟01背包类似:动态规划01背包问题
1、同样令dp[i][j]表示前i件物品恰好放入容量为j的背包中能获得的最大价值。
2、和01背包一样,完全背包问题的每种物品都有两种策略,不同的是。对第i件物品来说:
(1)不放第i件物品,那么dp[i][j] = dp[i-1][j],这步跟01背包是一样的。
(2)放第i件物品。这里的处理和01背包有所不同,因为01背包的每个物品只能选择一个,因此选择放第i件物品就意味着必须转移到dp[i-1][j-s[i]]这个状态;但是完全背包问题不同,完全背包如果选择放第i件物品之后并不是转移到dp[i-1][j-s[i]]这个状态;而是转移到dp[i][j-s[i]],这是因为每种物品可以放任意件。放了第i件物品后还可以继续放第i件物品,直到第二维的j-w[i]无法保持大于等于0为止。
(如果接着拿i,能获得最大价值为:dp[i][j-s[i]]+s[i],不接着拿i,能获得的最大价值为dp[i-1][j])
动态规划方程为:
if(j<s[i]) dp[i][j]=dp[i-1][j];
else{
if(dp[i-1][j]<dp[i][j-s[i]]+v[i]) dp[i][j]=dp[i][j-s[i]]+v[i];
else dp[i][j]=dp[i-1][j];
}
#include<bits/stdc++.h>
using namespace std;
void f(int dp[100][100],int *s,int *v,int n,int size);
int main(){
int i,j;
int dp[100][100],s[100],v[100];
int n,size;
cin>>size>>n;
for(i=1;i<=n;i++){
cin>>s[i]>>v[i];
}
f(dp,s,v,n,size);
}
void f(int dp[100][100],int *s,int *v,int n,int size)
{
int i,j;
for(i=0;i<=size;i++){ //初始化边界
// if(i>=s[1]) dp[1][i]=v[1];
//else dp[1][i]=0;
dp[0][i]=0;
}
for(i=1;i<=n;i++){
for(j=0;j<=size;j++){
if(j<s[i]) dp[i][j]=dp[i-1][j];
else{
if(dp[i-1][j]<dp[i][j-s[i]]+v[i]) dp[i][j]=dp[i][j-s[i]]+v[i]; //这步与01背包的区别
else dp[i][j]=dp[i-1][j];
}
}
}
cout<<dp[n][size]<<endl;
}
/*
13
6
4 8
3 9
5 7
6 10
2 6
1 2
*/