Hello!大家好,今天继续给大家带来一道动态规划的题目:

1268:【例9.12】完全背包问题

时间限制: 1000 ms         内存限制: 65536 KB
提交数: 25172     通过数: 13449

【题目描述】

  设有nn种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为MM,今从nn种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于MM,而价值的和为最大。

【输入】

  第一行:两个整数,MM(背包容量,M200M≤200)和NN(物品数量,N30N≤30);

  第2..N+12..N+1行:每行二个整数Wi,CiWi,Ci,表示每个物品的重量和价值。

【输出】

  仅一行,一个数,表示最大总价值。

【输入样例】

10 4
2 1
3 3
4 5
7 9

【输出样例】

max=12

【题目分析】

只分析重点部分

  这道题也是开一个二维数组:

  状态变量f[i][j]表示前i件物品放入容量j的背包的最大价值

  当前背包容量j,我们要考虑第i件物品能否放入是否放入

  第一种情况:

        当前背包容量j<w[i],不能放入,则f[i][j]=f[i-1][j]

  第二种情况:

  当前背包容量j>=w[i],能放入,但要考虑代价大小

(1) 若第i件物品不放入背包,则f[i][j]=f[i-1][j]

(2) 若第i件物品放入背包,则f[i][j]=f[i][j-w[i]]+c[i]

对于前i件物品,背包容量为j-w[i]时可能已经放入了第i件物品,容量为j时还可以再放入第i件物品,所以用f[i][j-w[i]]更新f[i][j]

举个栗子:

  

 

 

  

  由此可得转移方程:

    f[i][j]=f[i-1][j],(j<w[i]);

    f[i][j]=max(f[i-1][j],f[i][j-w[i]]+c[i]),(j>=w[i]);

  后面就不难了。

【代码思路】

 

【参考代码】

(保护知识产权,严禁抄袭)

(本题代码已在一本通上通过)

#include<iostream>
#define ll long long
using namespace std;
ll a[10001],b[10001],c[10001][10001];
int main(){
    int n,m;
    cin>>m>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i]>>b[i];
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(j<a[i]){
                c[i][j]=c[i-1][j];
            }else{
                c[i][j]=max(c[i-1][j],c[i][j-a[i]]+b[i]);
            }
        }
    }
    cout<<"max="<<c[n][m];
    return 0;
}

 《  再 见 ! ! ! 》