现在的位置: 首页 > 综合 > 正文

关于恰好装满背包的背包问题的理解

2019年02月19日 ⁄ 综合 ⁄ 共 1590字 ⁄ 字号 评论关闭

 因为某位同学最近在学背包,还老是问我问题,然后我就被拉去一起写背包问题了,不过也好,把以前的不会写的恰好装满的背包问题给写了。

其实还是挺好的。。。下面来说一说吧:

首先,你要把普通的背包熟悉(高深的我也不会了),然后如果是求最小值的恰好装满背包,那就先   int   INF = 1000000;  然后全部的初始化为 - INF,dp[1] = 0;  这样就可以了,类似的,当求最大值的恰好装满背包,那就全部初始化为INF
即可。

 题目号  TOJ  3232   TOJ 礼品兑换 
杭电 HDU 1114 Piggy-Bank

下面来两道例题吧

http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=3232 

这题是典型的多重背包,取最大值

#include<stdio.h>
#include<string.h>

const int N = 110;
const int INF = 10000000;    // 尽量定义的大一点,具体多大,我也不知道,应该这么大就可以了吧
int dp[100010];
int c[N], v[N];


int max(int x, int y)
{
    return x > y ? x : y;
}

int main()
{
    int n;
    int x, y, i, j;
    while(~scanf("%d",&n))
    {
        while(n--)
        {       
            scanf("%d%d",&x,&y);
            int price, weight, sum;
            int cnt= 1;
            for (i = 1; i <= y; i ++)                  // 用二进制的多重背包的方法
            {
                scanf("%d%d%d",&price, &sum, &weight);
                int t = 1;
                while(sum >= t)
                {
                    c[cnt] = t * price;
                    v[cnt++] = t * weight;
                    sum =sum - t;
                    t = t << 1;
                }
                if(sum)
                {
                    c[cnt] = sum * price;
                    v[cnt++] = sum * weight;
                }
            }
            for(i = 0; i <= x; i ++)
                dp[i] = - INF;                      // 初始化要注意
            dp[0] = 0;
            for (i = 1 ; i < cnt ; i ++ )
            {
                for(j = x; j >= v[i]; j --)
                dp[j] = max(dp[j], dp[j - v[i]] + c[i]);
            }
            if(dp[x] < 0)
                printf("This is impossible.\n");
            else
                printf("The maximum value is %d.\n",dp[x]);
        }
    }   
    return 0;
}

这题是杭电的01 - 背包 , 是取最小值的

http://acm.hdu.edu.cn/showproblem.php?pid=1114

#include <stdio.h>

const int N = 550;
int c[N];
int w[N];
int dp[10010];
const int INF = 10000000;

int min(int x, int y)
{
    return x < y ? x : y ;
}

int main()
{
    int n, m;
    int i, j;
    int a, b;
    int cc, ww;
    while(~scanf("%d",&n))
    {
        while(n --)
        {
            scanf("%d%d", &cc, &ww);
            scanf("%d", &m);
            for(i = 0; i <= ww - cc; i ++)
                dp[i] = INF;
            for(i = 0; i < m; i ++)
                scanf("%d%d",&c[i], &w[i]);
            dp[0] = 0;
            for(i = 0;i < m; i ++)
            {
                for(j = w[i]; j <= ww - cc; j ++)
                    dp[j] = min(dp[j - w[i]] + c[i], dp[j]);
            }
            if(dp[ww - cc] == INF)
                printf("This is impossible.\n");  
            else  
                printf("The minimum amount of money in the piggy-bank is %d.\n",dp[ww - cc]);  
        }
    }
    return 0;
}


抱歉!评论已关闭.