zcmu-1111: 松哥的困惑II(你的多重背包。不,是你的)

1111: 松哥的困惑II

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 166  Solved: 75
[Submit][Status][Web Board]

Description

松哥历尽千辛万苦终于找到女朋友了,但是一星期后又回到了单身的日子,松哥很生气后果很严重,所以松哥决定大吃一顿,但是由于松哥很胖,他要吃m千克的东西才会饱,松哥喜欢吃n样东西,每份东西有ai千克,需要bi元钱,只有ci份.松哥希望知道最少需要花多少钱才能使他吃饱,你能告诉他嘛.东西只能一份一份买,不能只买半份.

Input

多组测试数据.

每组测试数据的第一行包含两个正整数n,m(n<=100,m<=10000).

第二行有n个正整数a1,a2,a3,a4…an-1.(ai<=10000)

第三行有n个正整数b1,b2,b3,b4…bn-1.(bi<=100)

第四行有n个正整数c1,c2,c3,c4…cn-1.(ci<=100)

Output

对于每组数据输出能使松哥吃饱所需要花费最少的钱.如果松哥吃完了所有的东西还不能吃饱,请输出“impossible”.

Sample Input

3 1 1 1 2 1 2 1 1 1 1 3 100 1 1 2 1 2 1 1 1 1 2 2 2 1000 2 10 2 2 2 5 2 1000 2 10 2 2

Sample Output

1 Impossible 2 10

 

(1)先判断不可能的情况 

(2)剩下看代码的注释

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <map>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <iostream>
#define go(i,a,b) for(int i=a;i<=b;i++)
#define og(i,a,b) for(int i=a;i>=b;i--)
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn = 1e3 + 5;
typedef long long ll;
int a[maxn],b[maxn],c[maxn],dp[100100];
int main()
{
    int n,m;
    while(scanf("%d%d" ,&n,&m) != EOF)
    {
        mem(a);
        mem(b);
        mem(c);
        go(i,0,n-1) cin>>a[i];//weight
        go(i,0,n-1) cin>>b[i];//money
        go(i,0,n-1) cin>>c[i];//each num of each food
        
        int sum = 0,money = 0;
        go(i,0,n-1)
        {
            sum += a[i] * c[i];//全部都吃掉时的总千克数
            money += b[i] * c[i];//全部都吃掉时的总钱数
        }
        if(sum < m) cout<<"Impossible"<<endl;
        else
        {
            go(i,1,m) dp[i] = money;
            dp[0] = 0;
            go(i,0,n-1)
            {
                og(j,m,0)
                {
                    if(dp[j] != money)//当还没有到达
                    {
                        go(k,0,c[i])
                        {
                            if(j + k * a[i] >= m)//当前的之前时刻已吃的千克数 + 当前选择吃进去的千克数 已经能满足吃饱的条件的话
                                dp[m] = min(dp[m],dp[j] + k * b[i]);//选择花费钱最少的情况
                            else
                                dp[j + k * a[i]] = min(dp[j + k * a[i]] ,dp[j] + k * b[i]);//没吃饱的时候,选择当前时刻吃和不吃时花费的钱的最少的情况
                        }
                    }
                    
                }
            }
            cout<<dp[m]<<endl;
        }
    }
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值