【dp/完全背包】HRBUST 1627 猪猪罐

猪猪罐

Time Limit: 1000 MS Memory Limit: 32768 K

Description

ikki有一个小金库,这是一个猪猪罐,猪猪罐里面放了一些硬币。ikki知道了每种硬币的价值和重量,并且还知道空猪猪罐的重量,现在ikki想知道这个猪猪罐里至少放了价值为多少的硬币,她只能称出整个猪猪罐的总重量,你能帮她计算一下么?

Input

多组测试数据,第一行给出一个整数T表示测试数据的组数。

对于每组数据:

第一行输入两个正整数E、V,其中E表示空猪猪罐的重量,V表示放了硬币之后猪猪罐的总重量。(1<=E<=V<=10000)

第二行输入一个整数N表示硬币的种数。(1<=N<=50)

接下来的N行,每行两个整数v,w分别表示每种硬币的价值和重量。(1<=v<=50000,1<=w<=10000)

Output

对于每组数据输出猪猪罐中硬币价值可能的最小值,如果不存在则输出”Impossible”。

每组输出占一行。

Sample Input

3
10 110
2
1 1
30 50
10 110
2
1 1
50 30
1 6
2
10 3
20 4

Sample Output

60
100
Impossible

Author

周洲@hrbust

题意

给你一个存钱罐当中钱的重量,然后给你一定数量的钱币的重量和价值,问你是否有可能这些钱币组成这些重量的钱,有输出最小的组成价值,否则输出 不可能。

思路

完全背包问题,将除了第一个状态的dp[0]=0以外,其他设为inf,然后利用完全背包找到组合最小的情况,如果有就输出,不然就输出不可能。

坑点

dp[0]=0
一开始的第一次肯定要最小的啦,不然你inf+任何重量min之后肯定还是inf。

AC代码

#include<bits/stdc++.h>
using namespace std;
#define maxn 100007
#define inf 0x3f3f3f3f
int val[54];
int wei[54];
int dp[maxn];

void solve(void)
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int a,b,w;
        scanf("%d%d",&a,&b);
        int n;
        scanf("%d",&n);
        w = b-a;
        for(int i = 0 ; i < n ; i++)
        {
            scanf("%d%d",&val[i],&wei[i]);
        }
        for(int i = 1 ; i <= w ; i++)
        {
            dp[i] = inf;
        }
        for(int i = 0 ; i < n ; i++)
        {
            for(int j = wei[i] ; j <= w ; j++)
            {
                dp[j] = min(dp[j],dp[j-wei[i]]+val[i]);
                //printf("%d\n",dp[j]);
            }

        }
        if(dp[w]==inf)
            printf("Impossible\n");
        else
            printf("%d\n",dp[w]);
    }
}
int main(void)
{
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/peng0614/article/details/81271954