51nod 0-1背包详解dp(加一维优化)

来源:互联网 发布:网络机房日常维护项目 编辑:程序博客网 时间:2024/05/17 23:02
输入

第1行,2个整数,N和W中间用空格隔开。N为物品的数量,W为背包的容量。(1 <= N <= 100,1 <= W <= 10000)第2 - N + 1行,每行2个整数,Wi和Pi,分别是物品的体积和物品的价值。(1 <= Wi, Pi <= 10000)

输出

输出可以容纳的最大价值。

输入示例

3 62 53 84 9

输出示例
14
这个题直接说一下递推式的确定,51nod 上面这样写到令f(i,j)表示选决定了前i件物品,重量恰好为j的时候能获得的最大价值。对f(i,j)如果我们不选取第i件物品,则显然。然后我当初是这样理解的,既然能去第i件物品为什么不取。其实这句话这样理解,就是f(i,j)表示,物品一共有i件,这个时候背包的容量是j,所以对于递推式的确定,就是说如果不取这个第i件物品,那么这个时候的背包的容量j不会变,这时就判断第(i-1)件物品取还是不取,所以这个时候f(i, j) = f(i – 1,j),如果取了第i件物品,这个时候背包容量就是j-wi的重量加上i的价值,判断哪个总收益最高,所以总的递推式是f(i,j) = max(f(i – 1, j) , f(i-1,j - wi) + vi)。然后这个剩下就是用dp[n][w] 了,题解用i从1循环到n,j从0到w,这个时候就加了一个判断,就是如果这个时候第i件物品的重量大于背包直接承受的重量,则f(i, j) = f(i – 1,j)。所以源代码如下:

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int dp[105][10010];int wi[10010],pi[10010];int main(){int i,j;int n,w;scanf("%d%d",&n,&w);for(i=1;i<=n;i++)   {scanf("%d%d",&wi[i],&pi[i]);}for(i=1;i<=n;i++){for(j=0;j<=w;j++){if(j<wi[i]){dp[i][j]=dp[i-1][j];}else {dp[i][j]=max(dp[i-1][j],dp[i-1][j-wi[i]]+pi[i]);}}}printf("%d\n",dp[n][w]);return 0;}



优化代码:

//    >File Name: 0-1背包问题.cpp//    > Author: Webwei#include<iostream>#include<algorithm>#include<cstring>#define MAX 10010using namespace std;int dp[100010];int main(){int n,C,v,w;cin>>n>>C;memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++){cin>>v>>w;for(int j=C;j>=v;j--){if(dp[j]<dp[j-v]+w)  dp[j]=dp[j-v]+w;}}cout<<dp[C]<<endl;return 0;}







0 0
原创粉丝点击