HDU1114——Piggy-Bank(装满的完全揹包)

题目链接

       这道题是一道完全揹包练手很好的题,比较容易,但是与纯的完全揹包相比却做了部分很巧的改动。其一,这是一个要求装满的完全揹包。其二,这个揹包求得并不是最大值,而是最小值。那么如何解决这些变动呢?首先是看求最小值,这个好处理,那就是把max( )改成min( )就好了,但求最小值影响的却不只是函数的变化,还影响了对装满揹包的处理。

       我们知道,无论是01揹包还是完全揹包,在求揹包最大价值时处理方式都是初始化时除dp[0]=0外,其他的dp[i]都初始化为-∞。至于为什么这么处理,很多博客都有解释,大致是说这样处理,非法状况(即装不满的状况)都会是负值,而只有装满的状态才是正值。因为合法状态下的max函数都把负数给筛去了(一个正数和一个负数求max,当然取正数咯),但是若用的是min,那就的不到正确结果了,这就是为什么此题求最小值会给初始化带来影响,处理方式也很简单,就是直接将-∞改为+就好了,实现+就是给一个题目极端状况下都达不到的最大值。那么变动解决了,剩下的就是完全揹包的裸题了,采用一维数组处理,若dp[n]为+时,就是装不满的情况输出This is impossible.其他情况输出最小值就ok了。这题还有个小坑,就是输出末尾的句号。(表示少打了个点wrong了5遍很蛋疼。)


#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>

using namespace std;

typedef long long LL;
#define inf 1000000000

LL w[10005]={0};
LL v[10005]={0};
LL dp[10005];
int main()
{
    //freopen("in.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(w,0,sizeof(w));
        memset(v,0,sizeof(v));
        LL a, b;
        scanf("%lld%lld",&a,&b);
        LL W=b-a;
        dp[0]=0;
        for(int i=1;i<=W;i++)dp[i]=inf;
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld%lld",&v[i],&w[i]);
        for(int i=1;i<=n;i++)
            for(int j=w[i];j<=W;j++)
                dp[j]=min(dp[j],dp[j-w[i]]+v[i]);
        if(dp[W]==inf)printf("This is impossible.\n");
        else printf("The minimum amount of money in the piggy-bank is %lld.\n",dp[W]);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章