来发背包开开胃(OJ--3303

题目描述

多组输入。对于每组输入:

(1 <= n <= 3,1 <= V )接下来的n行,每行三个整数SiPiMi,分别代表第i种物品的数量,价格与质量()

输出

对于每组数据,输出一个整数代表答案。

思路:由于V范围太大所以不能用常规的背包来解决这个问题,而种数n很小,最大才是3,所以我就想到了用枚举每种物体放多少件的每种情况来求解该问题的答案。

示例输入

1 10
10 1 10

示例输出

100

DFS做法:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
ll s[5],p[5],m[5],mm,n,V;
void dfs(int x,ll money,ll vum)          //x--当前种数,money--上一层已用金额,vum--上一层已占用质量
{
    if(x>n)                                             //x大于n说明已枚举完所有n种物品,已到达最底层
    {
         mm=max(mm,vum);                //求此时最大质量
         return ;
    }
    for(int i=0;i<=s[x];i++)                   //枚举该种物体的件数
    {
           if((money+i*p[x])<=V)
                dfs(x+1,money+i*p[x],vum+i*m[x]);       //接着枚举下一种物体
            else
             return ;
    }
}
int main()
{
   while(~scanf("%lld %lld",&n,&V))
   {
      memset(s,0,sizeof(s));
      memset(p,0,sizeof(p));
      memset(m,0,sizeof(m));
      for(int i=1;i<=n;i++)
      scanf("%lld %lld %lld",&s[i],&p[i],&m[i]);
      mm=0;
      dfs(1,0,0);
      printf("%lld\n",mm);
   }
   return 0;
}
普通暴力:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
ll s[5],p[5],m[5];
int main()
{
    ll n,V;
    while(~scanf("%lld %lld",&n,&V))
    {
        memset(s,0,sizeof(s));
        memset(p,0,sizeof(p));
        memset(m,0,sizeof(m));
        for(int i=1; i<=n; i++)
            scanf("%lld %lld %lld",&s[i],&p[i],&m[i]);
        ll mm=0;
        for(int i=0; i<=s[1]; i++)                                      //n最大是3,最多才循环3层
            for(int j=0; j<=s[2]; j++)
                for(int k=0; k<=s[3]; k++)
                {
                    if((i*p[1]+j*p[2]+k*p[3])<=V)
                        mm=max(mm,i*m[1]+j*m[2]+k*m[3]);
                }
        printf("%lld\n",mm);
    }
    return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值