1. 程式人生 > >zcmu-1111: 鬆哥的困惑II(你的多重揹包。不,是你的)

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;
}