1111: 松哥的困惑II
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
HINT
一道dp題,雖然簡單,但是我不是很會= =。。。
就是這個跟揹包不一樣的地方是揹包不會超過m這個可能會超過m
然後用
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]);
進行狀態轉移
Code:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
int n,m;
int a[1005],b[1005],c[1005],dp[10005];
while(~scanf("%d %d",&n,&m))
{
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
for(int i=0; i<n; i++)
scanf("%d",&b[i]);
int abs=0,sum=0;
for(int i=0; i<n; i++)
{
scanf("%d",&c[i]);
abs+=c[i]*a[i];
sum+=c[i]*b[i];
}
if(abs<m)
printf("Impossible\n");
else
{
for (int i = 1; i <= m; i++)
dp[i] = sum;
dp[0] = 0;
for (int i = 0; i < n; i++)
{
for (int j = m - 1; j >= 0; j--)
{
if (dp[j] != sum)
{
for (int k = 1; k <= c[i]; k++)
{
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]);
}
}
}
}
printf("%d\n", dp[m]);
}
}
return 0;
}