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

来源:互联网 发布:华点软件学院诈骗 编辑:程序博客网 时间:2024/04/27 06:01

题目链接

       这道题是一道完全背包练手很好的题,比较容易,但是与纯的完全背包相比却做了部分很巧的改动。其一,这是一个要求装满的完全背包。其二,这个背包求得并不是最大值,而是最小值。那么如何解决这些变动呢?首先是看求最小值,这个好处理,那就是把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 1000000000LL 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;}


0 0
原创粉丝点击