HDU 2546

  这是一道01背包的变体。题目加了限制条件,当卡上金额大于等于5元时才能购买成功,我们不妨将这里的5元视为“0“,因为在DP过程中金额不能低于5,所以最后要用到的结果应该是dp[m-5]。既然我们保证了余额一直是大于等于5的,那么最后还能购买一次,所以,我们将最贵的一样菜留在最后,在DP的过程结束之后再购买,这样就能保证最后的余额最少。

  开始,我在写这道题的时候由于觉得要剩5元,于是将循环改为了 for i 1 to n

                                 for j m+5 to 5

  这样也是可以的,只是要注意最后结果应该使用dp[m],而不是dp[m+5],开始由于使用了dp[m+5],所以WA了。j从m+5到5,也是为了保证不小于5元,但是实际上m to 5就行了,这一点当时没有想清楚,造成了思路上的混乱。这是我思维上的一个弱点,大体方向是正确的,但是在细节上的思考还不够全面、细致,希望今后能够改正。

#include<stdio.h>
#include<string.h>
#define MAX_LMT 1010
int max(int,int);
int main()
{
    int n;
    while(scanf("%d",&n),n)
    {
    int cost[MAX_LMT],i,j,m,dp[MAX_LMT],most_expsv=0,recrd_expsv;
    for(i=1;i<=n;i++)
    {
        scanf("%d",&cost[i]);
        if(cost[i]>most_expsv)
        {
        most_expsv=cost[i];
        recrd_expsv=i;
        }
    }
    scanf("%d",&m);
    if(m<5)
    {
        printf("%d\n",m);
    }
    else
    {
        memset(dp,0,sizeof(dp));
        for(i=1;i<=n;i++)
        {
        for(j=m+5;j>=5;j--)
        {
            if(i!=recrd_expsv&&j>=cost[i]+5)
            {
            dp[j]=max(dp[j],dp[j-cost[i]]+cost[i]);
            }
        }
        }
        printf("%d\n",m-dp[m]-most_expsv);//使用dp[m],因为上面初始的是j+5
    }
    }
    return 0;
}
int max(int x,int y)
{
    return x>y?x:y;
}

 

#include<stdio.h>
#include<string.h>
#define MAX_LMT 1010
int max(int,int);
int main()
{
    int n;
    while(scanf("%d",&n),n)
    {
    int cost[MAX_LMT],i,j,m,dp[MAX_LMT],most_expsv=0,recrd_expsv;
    for(i=1;i<=n;i++)
    {
        scanf("%d",&cost[i]);
        if(cost[i]>most_expsv)
        {
        most_expsv=cost[i];
        recrd_expsv=i;
        }
    }
    scanf("%d",&m);
    if(m<5)
    {
        printf("%d\n",m);
    }
    else
    {
        memset(dp,0,sizeof(dp));
        for(i=1;i<=n;i++)
        {
        for(j=m;j>=0;j--)
        {
            if(i!=recrd_expsv&&j>=cost[i])
            {
            dp[j]=max(dp[j],dp[j-cost[i]]+cost[i]);
            }
        }
        }
        printf("%d\n",m-dp[m-5]-most_expsv);
    }
    }
    return 0;
}
int max(int x,int y)
{
    return x>y?x:y;
}
posted @ 2012-07-28 11:35  等待电子的砹  阅读(778)  评论(0编辑  收藏  举报