我是靠谱客的博主 安静汽车,最近开发中收集的这篇文章主要介绍C - Piggy-Bank HDU - 1114,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在acm能够做任何事情之前, 必须编制预算并获得必要的财政支持。这一行动的主要收入来自IBM。这个想法其实很简单,每当一些会员有一点小钱时,他就会把所有的硬币都扔到小猪存钱罐里。这个过程是不可逆转的, 除非打破猪,否则硬币不能拿出来。过了足够长的时间, 存钱罐里应该有足够的现金来支付所有需要支付的费用。

但存钱罐存在很大问题:不可能确定里面有多少钱。所以我们可能敲破猪才发现没有足够的钱。显然, 我们要避免这种不愉快的情况,唯一的可能是称重猪,并试图猜测里面有多少枚硬币。假设我们能够准确地确定猪的重量, 而且我们知道给定货币的所有硬币的重量。然后在存钱罐里有一些最低数量的钱, 我们可以保证。你的任务是找出这个最坏的情况, 并确定在存钱罐内的最低现金金额。

Input

输入由 T组测试用例组成。它们的数量T是在输入文件的第一行给出的。每个测试用例以包含两个整E和 F 的行开头(E和F以克为单位),它们表明了空猪和装满硬币的猪的重量。两个权重都以克为值。任何猪的重量都不会超过10公斤, 这意味着 1 < = E < = F < = 10000。在每个测试用例的第二行, 有一个整数数字 N (1 < = N < = 500), 给出给定货币中使用的各种硬币的数量。下面是 N 行, 每行都指定一种硬币类型。这些行包含两个整数, P, W (1 < = P < = 50000, 1 < = W < = 10000)。P 是硬币的价值, W是它的重量(以克为单位)。

Output

为每个测试用例只打印一行输出。该行必须包含句子 "The minimum amount of money in the piggy-bank is X." 其中 X 是可以实现的最低金额的硬币。如果无法准确达到总重量, 请打印一行 "This is 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

The minimum amount of money in the piggy-bank is 60.
The minimum amount of money in the piggy-bank is 100.
This is impossible.

 

#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <string.h>
using namespace std;
int value[5005];
int height[5005];
int dp[20005];
int main()
{
int T;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
int e,f;
memset(dp,0x3f,sizeof(dp));
dp[0] = 0;
scanf("%d %d",&e,&f);
int q = f-e;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d %d",&value[i],&height[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=height[i];j<=q;j++)
{
dp[j] = min(dp[j],dp[j-height[i]] + value[i]);
}
}
if(dp[q] == 0x3f3f3f3f)
printf("This is impossible.n");
else
printf("The minimum amount of money in the piggy-bank is %d.n",dp[q]);
}
}
return 0;
}

完全背包,主要学会了0x3f3f3f3f为无穷大,0x800000为无穷小

优点:

  1. 0x3f3f3f3f的十进制是1061109567,也就是10^9级别的(和0x7fffffff一个数量级),而一般场合下的数据都是小于10^9的,所以它可以作为无穷大使用而不致出现数据大于无穷大的情形。
  2. 另一方面,由于一般的数据都不会大于10^9,所以当我们把无穷大加上一个数据时,它并不会溢出(这就满足了“无穷大加一个有穷的数依然是无穷大”),事实上0x3f3f3f3f+0x3f3f3f3f=2122219134,这非常大但却没有超过32-bit int的表示范围,所以0x3f3f3f3f还满足了我们“无穷大加无穷大还是无穷大”的需求。
  3. 最后,0x3f3f3f3f还能给我们带来一个意想不到的额外好处:如果我们想要将某个数组清零,我们通常会使用memset(a,0,sizeof(a))这样的代码来实现(方便而高效),但是当我们想将某个数组全部赋值为无穷大时(例如解决图论问题时邻接矩阵的初始化),就不能使用memset函数而得自己写循环了(写这些不重要的代码真的很痛苦),我们知道这是因为memset是按字节操作的,它能够对数组清零是因为0的每个字节都是0,现在好了,如果我们将无穷大设为0x3f3f3f3f,那么奇迹就发生了,0x3f3f3f3f的每个字节都是0x3f!所以要把一段内存全部置为无穷大,我们只需要memset(a,0x3f,sizeof(a))。

所以在通常的场合下,0x3f3f3f3f真的是一个非常棒的选择。

无论哪种int类型都有其表达范围,其中
16位int能表示的范围为-32768~+32767
32位int能表示的范围为-2147483648~+2147483647

从这个可以看出,int是无法表达真正的无穷大和无穷小的。
一般有如下两种情况:
1 程序中对处理的数据规模有限制,比如程序中输入的数值只在0~100之间,那么可以设定无穷大为101,而无穷小为-1。因为它们也是在使用中无法达到的值。
2 程序中对数据规模没有明确的规定。但是既然应用的int类型,就必须是int类型可以容纳的,否则出现溢出就可能导致错误。 这样,可以用int所能表示的最大值和最小值用做无穷大和无穷小。
比如在32位情况下,无穷小可以是-2147483648,无穷大是2147483647。
如此长的一段数据是很难记忆的,由计算机对整型数据的存储原理可以得知,这两个数值的二进制值分别为0x80000000和0x7FFFFFFF。
类似的在16位下,无穷大为0x7FFF,无穷小为0x8000。

 

最后

以上就是安静汽车为你收集整理的C - Piggy-Bank HDU - 1114的全部内容,希望文章能够帮你解决C - Piggy-Bank HDU - 1114所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部