专题三1018

来源:互联网 发布:提前多久淘宝买高铁票 编辑:程序博客网 时间:2024/06/05 20:44

题目大意:

这道题目的大概意思是这样的,有一个存钱罐,我们知道存钱罐我们只能存,不好取,但我们又想知道里面存了多少钱,因此我们可以根据里面钱币的重量来估计里面的钱数。给出你它里面钱币的重量和硬币的种类数以及每种硬币的价值和重量,要求编程输出存钱罐里面的最少钱数。程序输入第一行正整数T,代表测试实例个数,然后每个测试实例的第一行输入两个正整数firstW和totalW,代表存钱罐的空罐的重量和装满钱币时的重量,下一行输入一个正整数n,代表硬币种类数,接下来的n行,每行输入两个正整数,代表这种硬币的价值和重量。程序输出,若这个测试实例有解的话,按照“The minimum amount of money in the piggy-bank is 答案.”,若无解的话输出“This is impossible.”。

解题思路:

这个专题一直在做这种类型的题目,一看就挺熟悉的,只是那些是让求最大价值,然而这个是求最小的价值。这道题目因为每种硬币的个数不做限制,假设就是无限多个,这道题可以看做是一道完全背包问题。lessValue[]数组代表重量为i的时候lessValue[i]代表此时背包的最小价值,钱罐种钱币的重量就是totalW=totalW-firstW,然后将数组lessValue初始化为INF(开头定义的一个数值很大的整数作为无穷大),将lessValue[0]赋值为0。定义了一个Coin的结构体变量,方便输入硬币的属性信息。然后接下来就是完全背包的状态转移方程了。LessValue[i]的值在第i种硬币选和不选种挑,选其中小的一个就可以了,类似于一种递归的方法。

感想:

这种题目做起来不容易,很难想,关键就在于套方程,有的时候循环的数据弄反了得到的答案也是反的,总之,做出来就很高兴啦。

代码如下:

#include<iostream>

using namespacestd;

int INF=99999999;

struct Coin//硬币,包括每种硬币的价值与重量

{

    intvalue;

    intweight;

}coin[501];

int lessValue[10001];

int min(inta,intb)//返回两个数种较小的一个

{

    if(a<b)

        returna;

    returnb;

}

int main()

{

    intT;//测试实例数

    cin>>T;

    intfirstW,totalW;//钱罐重量与装满前的总重量

    intn;//硬币种类

    while(T--)

    {

        cin>>firstW>>totalW;

        totalW-=firstW;

        cin>>n;

        for(inti=1;i<=n;i++)

            cin>>coin[i].value>>coin[i].weight;

        for(inti=1;i<=totalW;i++)

            lessValue[i]=INF;

        lessValue[0]=0;

        for(inti=1;i<=n;i++)

            for(intj=coin[i].weight;j<=totalW;j++)

                lessValue[j]=min(lessValue[j],lessValue[j-coin[i].weight]+coin[i].value);

        if(lessValue[totalW]!=INF)

            cout<<"The minimum amount of money in the piggy-bank is "<<lessValue[totalW]<<"."<<endl;

        else

            cout<<"This is impossible."<<endl;

               

    }

    return0;

}

0 0
原创粉丝点击