• 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种背包时所得的价值,这里我们要添加的不是前一个背包,而是当前背包。所以我们要考虑的当然是当前状态。

  • 相关阅读:
    进制
    流程控制
    运算符
    格式化输出
    数据结构-树的遍历
    A1004 Counting Leaves (30分)
    A1106 Lowest Price in Supply Chain (25分)
    A1094 The Largest Generation (25分)
    A1090 Highest Price in Supply Chain (25分)
    A1079 Total Sales of Supply Chain (25分)
  • 原文地址:https://www.cnblogs.com/gdvxfgv/p/5767460.html
Copyright © 2020-2023  润新知