POJ 1384 Piggy-Bank

来源:互联网 发布:html5 答题游戏源码 编辑:程序博客网 时间:2024/05/18 00:52

题目链接 POJ 1384


题意:有N种钱币,一种有面值P和重量W两种属性。现给出存钱罐净重和现重,要求往存钱罐里放钱,使存钱罐达到这种状态的最小总面值。


输入数据:

第一行一个T,代表测试数据组数

第二行两个数分别代表存钱罐净重和现重

第三行一个N,表示钱币种类。

以下N行,每行两个数P,W分别代表一种钱币的面值和重量。


解析: 变形的完全背包问题只要将dp[]的值初始化为最大,然后用状态转移方程

dp[v] = MIN(dp[v],dp[v -W[i]] + P[i]);   (v = 0...V , i = 0...N)(V表示钱币总重);

进行求解即可


代码如下:

#include <stdio.h>#include <string.h>#define MIN(a,b) ((a) > (b) ? (b) : (a))#define MAXN 550#define MAXM 10010int P[MAXN];int W[MAXN];int dp[MAXM];int n,m;void Init(){int i;memset(P,0,sizeof(P));memset(W,0,sizeof(W));scanf("%d %d",&n,&m);m -= n;scanf("%d",&n);for(i = 0;i < n;i ++){scanf("%d %d",P + i,W + i);}for(i = 0;i < MAXM ;i ++){dp[i] = 100000000;}}void DP(){int i,j;dp[0] = 0;for(i = 0;i < n;i ++){for(j = 0;j <= m;j ++){if(j - W[i] >= 0){dp[j] = MIN(dp[j],dp[j - W[i]] + P[i]);}}}}int main(){int T;while(scanf("%d",&T) != EOF){while(T --){Init();DP();if(dp[m] != 100000000){printf("The minimum amount of money in the piggy-bank is %d.\n",dp[m]);}else {printf("This is impossible.\n");}}}return 0;}