ZCMU 1111: 松哥的困惑II(dp)

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章