zcmu-1111: 鬆哥的困惑II(你的多重揹包。不,是你的)
阿新 • • 發佈:2018-12-15
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; }