HDU 5410 CRB and His Birthday(完全背包+01背包)

题目地址:点击打开链接

思路:把一种物品分为二种物品,它们花的钱相同,一种物品只能取一次,获得的糖果为a[i]+b[i],另一种物品能取无数次,获得的糖果为a[i],当二种物品取到时,第一种物品物品肯定已经取了,因为花的钱一样,第一种获得的糖果多,这样就转化为完全背包和01背包

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int w[1010],a[1010],b[1010],dp[2010];

int main()
{
    int t,n,m,i,j;
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d%d",&m,&n);
        for(i=1; i<=n; i++)
        {
            scanf("%d%d%d",&w[i],&a[i],&b[i]);
        }
        for(i=1; i<=n; i++)
        {
            for(j=m; j>=w[i]; j--)
            {
                dp[j] = max(dp[j],dp[j-w[i]] + a[i] + b[i]);
            }
            for(j=w[i]; j<=m; j++)
            {
                dp[j] = max(dp[j],dp[j-w[i]] + a[i]);
            }
        }
        printf("%d\n",dp[m]);
    }
}

超时代码:

#include<iostream>
#include<cstring>
#include<cstdio>

using namespace std;

int dp[1001][2010];
int w[1001],a[1001],b[1001];

int main()
{
    int t,m,n,i,j,max1,k;
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d%d",&m,&n);
        for(i=1; i<=n; i++)
        {
            scanf("%d%d%d",&w[i],&a[i],&b[i]);
        }
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=m; j++)
            {
                max1 = dp[i-1][j];
                for(k=1; k*w[i]<=j; k++)
                {
                    if(dp[i-1][j-k*w[i]]+k*a[i]+b[i] > max1)
                    {
                        max1 = dp[i-1][j-k*w[i]]+k*a[i]+b[i];
                    }
                }
                dp[i][j] = max1;
            }
        }
        printf("%d\n",dp[n][m]);
    }
    return 0;
}

错误代码1:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int w[1010],a[1010],b[1010],dp[2010];

int main()
{
    int t,n,m,i,j,max1;
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d%d",&m,&n);
        for(i=1; i<=n; i++)
        {
            scanf("%d%d%d",&w[i],&a[i],&b[i]);
        }
        for(i=1; i<=n; i++)
        {
            max1 = dp[m];
            for(j=m; j>=w[i]; j--)
            {
                dp[j] = max(dp[j],dp[j-w[i]] + a[i] + b[i]);
            }
            if(max1 != dp[m])
            {
                for(j=w[i]; j<=m; j++)
                    dp[j] = max(dp[j],dp[j-w[i]] + a[i]);
            }
        }
        printf("%d\n",dp[m]);
    }
}

错误代码2:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int w[1010],a[1010],b[1010],dp[2010];

int main()
{
    int t,n,m,i,j,max1;
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d%d",&m,&n);
        for(i=1; i<=n; i++)
        {
            scanf("%d%d%d",&w[i],&a[i],&b[i]);
        }
        for(i=1; i<=n; i++)
        {
            max1 = dp[w[i]];
            for(j=m; j>=w[i]; j--)
            {
                dp[j] = max(dp[j],dp[j-w[i]] + a[i] + b[i]);
            }
            if(max1 != dp[w[i]])
            {
                for(j=w[i]; j<=m; j++)
                    dp[j] = max(dp[j],dp[j-w[i]] + a[i]);
            }
        }
        printf("%d\n",dp[m]);
    }
}

超时代码直接枚举每种可能,直接超时,不会判断复杂度,一顿乱搞,错误代码错误的原因是,认为某件物品最小容量的都放了,大的肯定放了,或者最大容量都放了,最小容量肯定也放了,其实他们是没有关系的,大致原因就是放这个物品时会导致花费高同时性价比比这个物品高的物品剔除出去,虽然对小的没影响,对大的会有影响,或者来了一个花费高但同时性价比高的物品,大的会要这个物品,而小的不会要这个物品,因为它本身的费用太小

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值