动态规划-完全背包问题

思路:
跟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
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
*/

你可能感兴趣的:(算法,动态规划)