zoukankan      html  css  js  c++  java
  • HDU 4508 湫湫系列故事——减肥记I

    原题链接:点击此处

    解题思路:

    思路与01背包差不多,思路用二维数组表示:

    dp[i][v]=max{dp[i-1][v-k*b[i]]+k*a[i]|0<=k*b[i]<=v}

    其dp(i,v)表示“把i个物体放进容量为j的包里”。

    伪代码如下:

    for i=1..N
        for v=0..V
            f[v]=max{f[v],f[v-b[i]]+a[i]}
    View Code

      

    因此可以简单的写出程序。

    源代码如下:

    #include <cstdio>
    #include <cstring>
    
    int max(int a,int b)
    {
    return a>b?a:b;
    }
    
    int a[100003];
    int b[100003];
    int dp[100003];
    
    int main()
    {
        int n,m;
        while (~scanf("%d",&n))
        {
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++)
                scanf("%d %d",&a[i],&b[i]);
            scanf("%d",&m);
            for(int i=1;i<=n;i++)
               for(int j=b[i];j<=m;j++)
               dp[j]=max(dp[j],dp[j-b[i]]+a[i]);
            printf("%d
    ",dp[m]);
        }
        return 0;
    }
    View Code

    想必大家看出了和01背包的区别,这里的内循环是顺序的,而01背包是逆序的。
    现在关键的是考虑:为何完全背包可以这么写?
    在次我们先来回忆下,01背包逆序的原因?是为了是max中的两项是前一状态值,这就对了。
    那么这里,我们顺序写,这里的max中的两项当然就是当前状态的值了,为何?
    因为每种背包都是无限的。当我们把i从1到N循环时,f[v]表示容量为v在前i种背包时所得的价值,这里我们要添加的不是前一个背包,而是当前背包。所以我们要考虑的当然是当前状态。

  • 相关阅读:
    C++ using namespace std详解
    FlexEdit强大的文本编辑器(免费的!)
    串口扩展方案总结
    LED数码引脚图
    串口扩展方案总结
    C++ using namespace std详解
    Digital Mars Compiler简介及使用
    Digital Mars Compiler简介及使用
    poj1018
    poj3536
  • 原文地址:https://www.cnblogs.com/gdvxfgv/p/5767460.html
Copyright © 2011-2022 走看看