【水】背包问题的POJ例题

来源:互联网 发布:ubuntu 16.10 更新源 编辑:程序博客网 时间:2024/06/06 10:46

1 0-1背包问题

本来想做成一个七八个题的进阶集合,结果后面随着难度进阶个人认为不能单独归类为背包问题了,故此此篇比较水,就是在单纯介绍0-1背包问题

POJ 3624

题解:非常基础的模板题,套用0-1背包公式即可。

还是放上代码:

#include <iostream>#include <cstring>using namespace std;int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){int value[n+2],weight[n+2];for(int i=0;i<n;i++){cin>>weight[i]>>value[i];}int f[m+2];memset(f,0,sizeof(f));for(int i=0;i<n;i++){for(int j=m;j>=weight[i];j--){f[j]=max(f[j-weight[i]]+value[i],f[j]);}}cout<<f[m]<<endl;}}


POJ 3628

题意:给n个数,和一个数m,求n个数中的部分组成的和,与m的最小差(和必须大于等于m)

题解:没有给总容量需要输入过程中自己计算。其余还是常规0-1背包问题。物品的价值和重量此时可看做一个。

代码:

#include <iostream>#include <cstring>using namespace std;int main(){int n,b;while(cin>>n>>b){int weight[n+2];memset(weight,0,sizeof(weight));int sum=0;for(int i=0;i<n;i++){cin>>weight[i];sum+=weight[i];}int f[sum+2];memset(f,0,sizeof(f));for(int i=0;i<n;i++){        for(int j=sum;j>=weight[i];j--){            f[j]=max(f[j],f[j-weight[i]]+weight[i]);        }    }    int ans;    for(int i=1;i<=sum;i++){        if(f[i]>=b){            ans=f[i]-b;break;        }    }    cout<<ans<<endl;}}