Poweroj 1194(dp背包问题)

中秋节马上就要到了,小Y计划给基友买月饼。由于经济压力,小Y计算最多只用M元钱买月饼。超市有N种月饼,每种都有单价。由于有些月饼比较抢手,剩下的个数有限,有的月饼有无限多个。小Y的基友对于每种月饼都有不一样的喜爱程度。小Y为了让基友尽可能的高兴,他想用计算之内的钱购买的月饼使得基友的喜爱程度最高。(每个月饼都有一个喜爱度。基友的喜爱程度是小Y购买到月饼的喜爱度的总和。)

 

多组输入。首先输入一个M,N。表示小Y计划用的钱和超市的月饼种类。(0 < M <= 10000,0 < N <= 5000)接下来n行,每行3个整likei,wi,numi,分别表示第i种月饼的喜爱度,单价和个数。(0 <= likei <= 10000,100 <= wi <= 10000,土豪月饼,单价比较高,numi=-1表示月饼有无限多个,否则0 <= numi <= 10000,保证个数有限的种类 <= 10)
输出一行整数表示最大的喜爱度。
100 11 100 -1500 11 101 1

11

题意:就如同题目描述一样。

代码:

#include
#include
#include
using namespace std;
const int maxn=100005;
int dp[maxn],love[maxn],price[maxn],countt[maxn];
int main()
{
    int i,j,k,n,m;
    while(~scanf("%d%d",&m,&n))
    {
        memset(dp,0,sizeof(dp));
        for(i=1;i<=n;i++)
            scanf("%d%d%d",&love[i],&price[i],&countt[i]);
            for(i=1;i<=n;i++)
            {
                if(countt[i]==1)//01背包,每个物品只有1个,可以选择放还是不放
                {
                    for(j=m;j>=price[i];j--)
                        dp[j]=max(dp[j],dp[j-price[i]]+love[i]);
                }
                else if(countt[i]=-1)//完全背包,每个物品都有无限个使用
                {
                    for(j=price[i];j<=m;j++)
                        dp[j]=max(dp[j],dp[j-price[i]]+love[i]);
                }
                else
                {
                    for(k=1;k<=countt[i];k++)//多重背包,第看k件物品最多有m件可以用
                        for(j=m;j>=price[i];j--)
                        dp[j]=max(dp[j],dp[j-price[i]]+love[i]);
                }
            }
        printf("%d\n",dp[m]);
    }
}

你可能感兴趣的:(POWEROJ)