砝码称重3

参考

https://blog.csdn.net/livelylittlefish/article/details/6555347

假设有280g盐,有一架天平,有两个砝码,分别是4g和14g 。能否在3次内将280g食盐分为100g和180g两堆,请详细描述你的解决方法。

这是另外一种砝码称重问题,类似,但是又不同。砝码称重这个是给定无限数量砝码,只需计算能不能组成一个重量,不用知道如何组合。砝码称重1是给定砝码个数和重量,以及可以组合的重量,求出任意一种重量是如何组合的。砝码称重2给定重量和拆分的砝码个数,求拆分后每个砝码的重量。这道题是给定重量和砝码,求如何拆分物体。看似相同,实际上每一个都不一样的。

我们知道4和14可以有这几种组合 0 4 10 14 18,那么问题就是280g物品如何在3次内(说是3次内,基本上就是至少需要3次,我们就按照给定的最大条件来计算,因为如果2次可以,那么3次肯定也可以)用上面的几种砝码组合,拆出100和180.

如果是3次,那么盐肯定是4堆。不过感觉上好像帮不上什么忙。上面参考的作者对问题做了数学分析,可以参考一下。

求解的话就是穷举,分别用这几种砝码组合方式拆分盐,把每次拆分的结果再递归拆分,3次之后得到拆分的所有可能,然后计算有没有符合条件的方案。

这里可以看出,第一次不管如何拆分都是偶数,因为砝码和盐堆都是偶数,怎么组合也没有奇数。

那么第二次呢?可能会出现奇数,比如用14的组合称出14g盐,14g盐平分就是7g。如果出现了奇数,按照题目是拆分成100g和180g是整数,所以就没办法拆分了,因为砝码只有偶数,如果用砝码拆分奇数,得到的会有小数,有了小数,这两堆就没办法继续了,因为再往下,小数会更多,而其他的堆没有小数,所以只能这一堆组合。如果拆分其他堆呢,因为另一堆是偶数,只能平分,也没意义,最后导致与没拆分一样。

如果第二次没有奇数,那么第三次出现奇数也只有平分,那么就不可能出现100g和180g。因为第二次比如得出盐堆a b c,a b c都是偶数,如果把a平分为a1 a2,并且是奇数,那么a1 a2没办法与b c组合,因为b c是偶数,没办法相加得出100g和180g两个偶数,所以只能a1和a2组合,那么就是要求第二次就可以得出100和180,也就是与第二步一样,与没拆分结果一样。

因为砝码和盐堆都是偶数,拆分的也是偶数,出现奇数只能平分,如果一路平分下去,那就要求第一步就直接得出了结果。因为如果只有一个偶数变成奇数,那么只能这两个奇数组合,与没拆分这一步结果一样。如果两个偶数拆分成奇数,那么要么拆分的两堆相互组合,要么内部自己组合,不管怎么组合,都是与没进行这一步结果一样。

所以拆分过程中不可能出现奇数,如果出现,就可以直接跳过了。可以帮我们减少一些计算。

我们看一下上面作者的第一种方法

#define Max_Num 5
using namespace std;
int total = 280;  //the total weight of the heap of salt
int heap1 = 100, heap2 = 180;  //the target weight of the two samll heaps of salt
int wst[] = { 0, 4, 10, 14, 18 };  //all cases of the weights combination
/* the first division result */
int x[Max_Num] = { 0 }, y[Max_Num] = { 0 };
/* the second division result */
int x1[Max_Num][Max_Num] = { {0} };
int x2[Max_Num][Max_Num] = { {0} };
int yy1[Max_Num][Max_Num] = { {0} };
int y2[Max_Num][Max_Num] = { {0} };
/* the third division result */
int x11[Max_Num][Max_Num][Max_Num] = { {{0}} }, x12[Max_Num][Max_Num][Max_Num] = { {{0}} };
int x21[Max_Num][Max_Num][Max_Num] = { {{0}} }, x22[Max_Num][Max_Num][Max_Num] = { {{0}} };
int y11[Max_Num][Max_Num][Max_Num] = { {{0}} }, y12[Max_Num][Max_Num][Max_Num] = { {{0}} };
int y21[Max_Num][Max_Num][Max_Num] = { {{0}} }, y22[Max_Num][Max_Num][Max_Num] = { {{0}} };
/** the first division, according to z=x+y, x <= y */
void weight1()
{
    int z = total;
    int k = 0, w = 0;
    for (k = 0; k < Max_Num; k++)
    {
        w = wst[k];
        x[k] = z / 2 - w;  //divide z
        y[k] = z / 2 + w;
        if (x[k] % 2 != 0)  //no need to judge y[k]
            x[k] = y[k] = 0;
    }
}
void weight2()
{
    int i = 0, k = 0, w = 0;
    for (i = 0; i < Max_Num; i++)
    {
        if (x[i] == 0)  //no need to judge y[i]
            continue;
        for (k = 0; k < Max_Num; k++)
        {
            w = wst[k];
            x1[i][k] = (x[i] - w) / 2;  //divide x
            x2[i][k] = (x[i] + w) / 2;
            if (x1[i][k] % 2 != 0)  //no need to judge x2[i][k]
                x1[i][k] = x2[i][k] = 0;
            if (x[i] == y[i])  //to avoid repeatance
                continue;
            yy1[i][k] = (y[i] - w) / 2;  //divide y
            y2[i][k] = (y[i] + w) / 2;
            if (yy1[i][k] % 2 != 0)  //no need to judge y2[i][k]
                yy1[i][k] = y2[i][k] = 0;
        }
    }
}
void weight3()
{
    int i = 0, j = 0, k = 0, w = 0;
    for (i = 0; i < Max_Num; i++)
    {
        if (x[i] == 0)  //no need to judge y[i]
            continue;
        for (j = 0; j < Max_Num; j++)
        {
            for (k = 0; k < Max_Num; k++)
            {
                w = wst[k];
                if (x1[i][j] != 0)  //divide x1[i][j]
                {
                    x11[i][j][k] = (x1[i][j] - w) / 2;
                    x12[i][j][k] = (x1[i][j] + w) / 2;
                    if (x11[i][j][k] % 2 != 0)  //x11[i][j][k] and x12[i][j][k] must be even
                        x11[i][j][k] = x12[i][j][k] = 0;
                }
                if (x2[i][j] != 0 && x1[i][j] != x2[i][j])  //divide x2[i][j], and to avoid repeatance
                {
                    x21[i][j][k] = (x2[i][j] - w) / 2;
                    x22[i][j][k] = (x2[i][j] + w) / 2;
                    if (x21[i][j][k] % 2 != 0)  //x21[i][j][k] and x22[i][j][k] must be even
                        x21[i][j][k] = x22[i][j][k] = 0;
                }
                if (yy1[i][j] != 0)  //divide yy1[i][j]
                {
                    y11[i][j][k] = (yy1[i][j] - w) / 2;
                    y12[i][j][k] = (yy1[i][j] + w) / 2;
                    if (y11[i][j][k] % 2 != 0)  //y11[i][j][k] and y12[i][j][k] must be even
                        y11[i][j][k] = y12[i][j][k] = 0;
                }
                if (y2[i][j] != 0 && yy1[i][j] != y2[i][j])  //divide y2[i][j], and to avoid repeatance
                {
                    y21[i][j][k] = (y2[i][j] - w) / 2;
                    y22[i][j][k] = (y2[i][j] + w / 2;
                    if (y21[i][j][k] % 2 != 0)  //y21[i][j][k] and y22[i][j][k] must be even
                        y21[i][j][k] = y22[i][j][k] = 0;
                }
            }
        }
    }
}
void dump_correct_results()
{
    int i = 0, j = 0, k = 0;
    for (i = 0; i < Max_Num; i++)
    {
        if (x[i] == 0)  //no need to judge y[i]
            continue;
        for (j = 0; j < Max_Num; j++)
        {
            if (x1[i][j] == 0)  //no need to judge x2[i][j]
                continue;
            for (k = 0; k < Max_Num; k++)
            {
                if (x11[i][j][k] != 0 && (x11[i][j][k] + x2[i][j] == heap1 || x12[i][j][k] + x2[i][j] == heap1))  //divide x1[i][j]
                {
                    printf("%d = %d + %d\n", total, x[i], y[i]);
                    printf("%d = %d + %d\n", x[i], x1[i][j], x2[i][j]);
                    printf("%d = %d + %d\n\n", x1[i][j], x11[i][j][k], x12[i][j][k]);
                }
            }
            for (k = 0; k < Max_Num; k++)
            {
                if (x21[i][j][k] != 0 && (x21[i][j][k] + x1[i][j] == heap1 || x22[i][j][k] + x1[i][j] == heap1))  //divide x2[i][j]
                {
                    printf("%d = %d + %d\n", total, x[i], y[i]);
                    printf("%d = %d + %d\n", x[i], x1[i][j], x2[i][j]);
                    printf("%d = %d + %d\n\n", x2[i][j], x21[i][j][k], x22[i][j][k]);
                }
            }
        }
        for (j = 0; j < Max_Num; j++)
        {
            if (yy1[i][j] == 0)  //no need to judge y2[i][j]
                continue;
            for (k = 0; k < Max_Num; k++)
            {
                if (y11[i][j][k] != 0 && (y11[i][j][k] + y2[i][j] == heap1 || y12[i][j][k] + y2[i][j] == heap1))  //divide yy1[i][j]
                {
                    printf("%d = %d + %d\n", total, x[i], y[i]);
                    printf("%d = %d + %d\n", y[i], yy1[i][j], y2[i][j]);
                    printf("%d = %d + %d\n\n", yy1[i][j], y11[i][j][k], y12[i][j][k]);
                }
            }
            for (k = 0; k < Max_Num; k++)
            {
                if (y21[i][j][k] != 0 && (y21[i][j][k] + yy1[i][j] == heap1 || y22[i][j][k] + yy1[i][j] == heap1))  //divide y2[i][j]
                {
                    printf("%d = %d + %d\n", total, x[i], y[i]);
                    printf("%d = %d + %d\n", y[i], yy1[i][j], y2[i][j]);
                    printf("%d = %d + %d\n\n", y2[i][j], y21[i][j][k], y22[i][j][k]);
                }
            }
        }
    }
}

struct MyStruct
{
    int weight;//当前是多重的盐
    int fm;//通过哪种砝码得到的
    MyStruct()
    {
        weight = 0;
        fm = 0;
    }
};
//num 已经拆分了多少次
void cf(int num, int* cfyan)
{
    if (num == 3)
    {
        if (cfyan[0] + cfyan[1] == 100 || cfyan[2] + cfyan[3] == 180)
        {
            cout << cfyan[0] << "||" << cfyan[1] << "||" << cfyan[2] << "||" << cfyan[3];
        }
        else if (cfyan[0] + cfyan[2] == 100 || cfyan[1] + cfyan[3] == 180)
        {
            cout << cfyan[0] << "||" << cfyan[2] << "||" << cfyan[1] << "||" << cfyan[3];
        }
        else if (cfyan[0] + cfyan[3] == 100 || cfyan[1] + cfyan[2] == 180)
        {
            cout << cfyan[0] << "||" << cfyan[3] << "||" << cfyan[1] << "||" << cfyan[2];
        }
    }
}
int main()
{
    int yan = 280;
    int fm[] = { 0, 4, 10, 14, 18 };
    int cfyan[] = { 0, 0, 0, 0 };
    {
        weight1();
        weight2();
        weight3();
        dump_correct_results();
    }
    char inchar;
    cin >> inchar;
}

原作者的代码有个问题,没有覆盖作者第一篇提到的,先用一个砝码称出对应的盐,然后再拆分,作者的逻辑都是平分再去掉对应的砝码重量。

这是上面作者的第二种解法,用链表组成树

#define Max_Num 5
#define To_Be_Devided 2
#define total 280  //the total weight of the heap of salt
int wst[] = { 0, 4, 10, 14, 18 };  //all cases of the weights combination
int heap1 = 100, heap2 = 180;  //the target weight of the two samll heaps of salt
struct Division_Node
{
    int parent_be_divided_;  //array to_be_divided_[] divided from its parent with this index
    int step_;  //the node step in the division process
    int heap_[Max_Num - 1];  //all divisions of its parent position for all weights
    int to_be_divided_[2];  //salt heap index to be divided in next step
    struct Division_Node *next_[2 * Max_Num];  //all pointers to all child divisions
    int child_;  //the numbe of children (not NULL in array next_)
};
//the root, for step 1, heap_[0] will be divided
static struct Division_Node root = { 0, 0, {total}, {0}, {NULL}, 0 };
/** the first division, according to z=x+y, x <= y */
void weight1()
{
    int div = 0, k = 0, w = 0;
    struct Division_Node *cur = &root;
    int child = 0;
    int step = 1;
    for (div = 0; div < To_Be_Devided - 1; div++)  //for step 1, only divide heap_[0]
    {
        int curpos = cur->to_be_divided_[div];
        int z = cur->heap_[curpos];  //the current heap to be divided
        for (k = 0; k < Max_Num; k++)
        {
            w = wst[k];
            int x = (z - w) / 2;  //divide z
            int y = (z + w) / 2;
            if (x % 2 != 0)  //no need to judge y[k]
                continue;
            //new a node in step 1
            struct Division_Node *node1 = (struct Division_Node*)malloc(sizeof(struct Division_Node));
            memset(node1, 0, sizeof(struct Division_Node));
            node1->parent_be_divided_ = curpos;
            node1->step_ = step;
            node1->heap_[curpos] = x;
            node1->heap_[step] = y;
            node1->to_be_divided_[0] = curpos;
            node1->to_be_divided_[1] = step;
            cur->next_[child++] = node1;  //link root and node1
        }
    }
    cur->child_ = child;
}
/** the second division, according to x=x1+x2, y=y1+y2, x1<=x2, y1<=y2
  but, x and y are saved in node1->to_be_divided_[0] and node1->to_be_divided_[1].
  so, unify them to be as x.
 */
void weight2()
{
    int div = 0, i = 0, k = 0, w = 0;
    struct Division_Node *cur = &root;
    int step = 2;
    for (i = 0; i < cur->child_; i++)  //for each node1 in step1
    {
        struct Division_Node *node1 = cur->next_[i];  //step 2 will use all nodes created in step 1
        //to avoid repeatance
        int to_be_divided = To_Be_Devided;
        if (node1->heap_[node1->to_be_divided_[0]] == node1->heap_[node1->to_be_divided_[1]])
            to_be_divided--;
        int child = 0;
        for (div = 0; div < to_be_divided; div++)  //for step 2, will divide x=heap_[0], y=heap_[1] of node1
        {
            int curpos = node1->to_be_divided_[div];
            int x = node1->heap_[curpos];  //the current heap to be divided
            for (k = 0; k < Max_Num; k++)
            {
                w = wst[k];
                int x1 = (x - w) / 2;  //divide x or y, use x in order to be in a uniform
                int x2 = (x + w) / 2;
                if (x1 % 2 != 0)  //no need to judge x2
                    continue;
                //new a node in step 2
                struct Division_Node *node2 = (struct Division_Node*)malloc(sizeof(struct Division_Node));
                memset(node2, 0, sizeof(struct Division_Node));
                memcpy(node2->heap_, node1->heap_, (Max_Num - 1) * sizeof(int));  //copy from its parent
                node2->parent_be_divided_ = curpos;
                node2->step_ = step;
                node2->heap_[curpos] = x1;
                node2->heap_[step] = x2;
                node2->to_be_divided_[0] = curpos;
                node2->to_be_divided_[1] = step;
                node1->next_[child++] = node2;  //link current node1 and node2
            }
        }
        node1->child_ = child;
    }
}
/** the third division, according to
  x1=x11+x12, y1=y11+y12, x11<=x12, y11<=y12
  x2=x21+x22, y2=y21+y22, x21<=x22, y21<=y22
  but, x1 or x2 or y1 or y2 is saved in heap_ of each node2 with index node2->to_be_divided_[0]
  and node2->to_be_divided_[1]. so, unify them to be as x1.
 */
void weight3()
{
    int div = 0, i = 0, j = 0, k = 0, w = 0;
    struct Division_Node *cur = &root;
    int step = 3;
    for (i = 0; i < cur->child_; i++)  //for each node1 in step1
    {
        struct Division_Node *node1 = cur->next_[i];
        for (j = 0; j < node1->child_; j++)  //for each node2 of node1 in step2
        {
            struct Division_Node *node2 = node1->next_[j];
            //to avoid repeatance
            int to_be_divided = To_Be_Devided;
            if (node2->heap_[node2->to_be_divided_[0]] == node2->heap_[node2->to_be_divided_[1]])
                to_be_divided--;
            int child = 0;
            for (div = 0; div < to_be_divided; div++)  //for step 3, will divide x1=heap_[0], x2=heap_[2] of node2
            {
                int curpos = node2->to_be_divided_[div];
                int x1 = node2->heap_[curpos];  //the current heap to be divided, x1, or x2, or y1, or y2
                for (k = 0; k < Max_Num; k++)
                {
                    w = wst[k];
                    int x11 = (x1 - w) / 2;  //divide x or y, use x in order to be in a uniform
                    int x12 = (x1 + w) / 2;
                    if (x11 % 2 != 0)  //no need to judge x12
                        continue;
                    //new a node in step 3
                    struct Division_Node *node3 = (struct Division_Node*)malloc(sizeof(struct Division_Node));
                    memset(node3, 0, sizeof(struct Division_Node));
                    memcpy(node3->heap_, node2->heap_, (Max_Num - 1) * sizeof(int));  //copy from its parent
                    node3->parent_be_divided_ = curpos;
                    node3->step_ = step;
                    node3->heap_[curpos] = x11;
                    node3->heap_[step] = x12;
                    node3->to_be_divided_[0] = curpos;  //in fact, this array in step3 needed for dump
                    node3->to_be_divided_[1] = step;
                    node2->next_[child++] = node3;  //link current node2 and node3
                }
            }
            node2->child_ = child;
        }
    }
}
void dump_correct_results(struct Division_Node* node)
{
    int i = 0, j = 0, k = 0;
    struct Division_Node *cur = node;
    for (i = 0; i < cur->child_; i++)  //for each node1 in step1
    {
        struct Division_Node *node1 = cur->next_[i];
        for (j = 0; j < node1->child_; j++)  //for each node2 of node1 in step2
        {
            struct Division_Node *node2 = node1->next_[j];
            for (k = 0; k < node2->child_; k++)  //for each node3 of node2 in step 3
            {
                struct Division_Node *node3 = node2->next_[k];
                /** unify them into the following equations
                  z = x + y, x <= y
                  x = x1 + x2, x1 <= x2
                  x1 = x11 + x12, x11 <= x12
                 */
                int x11 = node3->heap_[node3->to_be_divided_[0]];
                int x12 = node3->heap_[node3->to_be_divided_[1]];
                int x2index = 0;
                if (node3->parent_be_divided_ == node2->to_be_divided_[0])
                    x2index = node2->to_be_divided_[1];
                else
                    x2index = node2->to_be_divided_[0];
                int x2 = node2->heap_[x2index];
                if (x11 + x2 == heap1 || x12 + x2 == heap1)
                {
                    printf("%d = %d + %d\n", total, node1->heap_[node1->to_be_divided_[0]],
                        node1->heap_[node1->to_be_divided_[1]]);
                    printf("%d = %d + %d\n", node1->heap_[node2->parent_be_divided_],
                        node2->heap_[node2->to_be_divided_[0]],
                        node2->heap_[node2->to_be_divided_[1]]);
                    printf("%d = %d + %d\n\n", node2->heap_[node3->parent_be_divided_], x11, x12);
                }
            }
        }
    }
}
void free_all_nodes(struct Division_Node* node)
{
    int i = 0, j = 0, k = 0;
    struct Division_Node *cur = node;
    for (i = 0; i < cur->child_; i++)  //for each node1 in step1
    {
        struct Division_Node *node1 = cur->next_[i];
        for (j = 0; j < node1->child_; j++)  //for each node2 of node1 in step2
        {
            struct Division_Node *node2 = node1->next_[j];
            for (k = 0; k < node2->child_; k++)  //for each node3 of node2 in step 3
            {
                struct Division_Node *node3 = node2->next_[k];
                free(node3);
            }
            free(node2);
        }
        free(node1);
    }
}
int main(/* int argc, char** argv */)
{
    weight1();
    weight2();
    weight3();
    dump_correct_results(&root);
    free_all_nodes(&root);

    char inchar;
    cin >> inchar;
}

我做了改进,增加了单独称出一些盐的条件,不足之处,就是有重复数据,没有判断。

int fmweight[] = { 0, 4, 10, 14, 18 };
struct MNODE
{
    vector<int> mweight;//当前拆分的盐堆
    vector<MNODE*> mnext;//当前盐堆对应的拆分
};
void devsalt(MNODE* pnode)
{
    if (pnode->mweight.size() == 4)
    {
        if (pnode->mweight[0] + pnode->mweight[1] == 100)
        {
            cout << pnode->mweight[0] << " " << pnode->mweight[1] << "||" << pnode->mweight[2] << " " << pnode->mweight[3] << endl;
        }
        else if (pnode->mweight[0] + pnode->mweight[2] == 100)
        {
            cout << pnode->mweight[0] << " " << pnode->mweight[2] << "||" << pnode->mweight[1] << " " << pnode->mweight[3] << endl;
        }
        else if (pnode->mweight[0] + pnode->mweight[3] == 100)
        {
            cout << pnode->mweight[0] << " " << pnode->mweight[3] << "||" << pnode->mweight[1] << " " << pnode->mweight[2] << endl;
        }
        else if (pnode->mweight[1] + pnode->mweight[2] == 100)
        {
            cout << pnode->mweight[1] << " " << pnode->mweight[2] << "||" << pnode->mweight[0] << " " << pnode->mweight[3] << endl;
        }
        else if (pnode->mweight[1] + pnode->mweight[3] == 100)
        {
            cout << pnode->mweight[1] << " " << pnode->mweight[3] << "||" << pnode->mweight[0] << " " << pnode->mweight[2] << endl;
        }
        else if (pnode->mweight[2] + pnode->mweight[3] == 100)
        {
            cout << pnode->mweight[2] << " " << pnode->mweight[3] << "||" << pnode->mweight[0] << " " << pnode->mweight[1] << endl;
        }
    }
    else
    {
        for (int i = 0; i < pnode->mweight.size(); i++)
        {
            for (int j = 0; j < 5; j++)
            {
                {
                    int x = (pnode->mweight[i] - fmweight[j]) / 2;
                    int y = (pnode->mweight[i] + fmweight[j]) / 2;
                    if (x % 2 == 0)
                    {
                        MNODE* tnode = new MNODE;
                        for (int p = 0; p < pnode->mweight.size(); p++)
                        {
                            if (p != i)
                            {
                                tnode->mweight.emplace_back(pnode->mweight[p]);
                            }
                        }
                        tnode->mweight.emplace_back(x);
                        tnode->mweight.emplace_back(y);
                        pnode->mnext.emplace_back(tnode);
                        devsalt(tnode);
                    }
                }
                if(fmweight[j] > 0)
                {
                    int x = pnode->mweight[i] - fmweight[j];
                    int y = fmweight[j];
                    if (x > 0 && x % 2 == 0)
                    {
                        MNODE* tnode = new MNODE;
                        for (int p = 0; p < pnode->mweight.size(); p++)
                        {
                            if (p != i)
                            {
                                tnode->mweight.emplace_back(pnode->mweight[p]);
                            }
                        }
                        tnode->mweight.emplace_back(x);
                        tnode->mweight.emplace_back(y);
                        pnode->mnext.emplace_back(tnode);
                        devsalt(tnode);
                    }
                }
            }
        }
    }
}
int main()
{
    MNODE* phead = new MNODE;
    phead->mweight.emplace_back(280);
    devsalt(phead);
    char inchar;
    cin >> inchar;
}

虽然增加了单独称出某些盐的方法,但是并没有增加结果,因为如果单独称出某些盐,这道题只能是利用已知的盐堆,这样的话,情况更多,这里就没有处理。别忘了释放内存。

原文地址:https://www.cnblogs.com/studywithallofyou/p/12120992.html

时间: 2024-11-04 09:37:31

砝码称重3的相关文章

1449 砝码称重

1449 砝码称重 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 现在有好多种砝码,他们的重量是 w0,w1,w2,...  每种各一个.问用这些砝码能不能表示一个重量为m的东西. 样例解释:可以将重物和3放到一个托盘中,9和1放到另外一个托盘中. Input 单组测试数据. 第一行有两个整数w,m (2 ≤ w ≤ 10^9, 1 ≤ m ≤ 10^9). Output 如果能,输出YES,否则输出NO. Input示例

2144 砝码称重 2

2144 砝码称重 2 http://codevs.cn/problem/2144/ 题目描述 Description 有n个砝码,现在要称一个质量为m的物体,请问最少需要挑出几个砝码来称? 注意一个砝码最多只能挑一次 输入描述 Input Description 第一行两个整数n和m,接下来n行每行一个整数表示每个砝码的重量. 输出描述 Output Description 输出选择的砝码的总数k,你的程序必须使得k尽量的小. 样例输入 Sample Input 3 10591 样例输出 Sa

【dp】砝码称重

砝码称重 来源:NOIP1996(提高组)  第四题 [问题描述]     设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000),用他们能称出的重量的种类数. [输入文件]   a1  a2  a3  a4  a5  a6     (表示1g砝码有a1个,2g砝码有a2个,…,20g砝码有a6个,中间有空格). [输出文件]   Total=N     (N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况). [输入样例]     1 1 0 0 0

HFUT 1354.砝码称重(安徽省2016“京胜杯”程序设计大赛 A)

砝码称重 Time Limit: 1000 MS Memory Limit: 65536 KB Total Submissions: 12 Accepted: 10 Description 小明非常喜爱物理,有一天,他对物理实验室中常用的弹簧拉力计产生了兴趣.实验室中有两种质量不同的砝码,小明分别用a个第一种砝码放在弹簧拉力计上和b个第二种砝码放在弹簧拉力计上,假设每增加单位重量的砝码,弹簧拉力计的长度增加1,那么两次称量弹簧拉力计的长度差是多少呢?(假设拉力计不发生非弹性形变) Input 第

砝码称重问题二

题目描述 有一组砝码,重量互不相等,分别为m1.m2.m3……mn:它们可取的最大数量分别为x1.x2.x3……xn. 现要用这些砝码去称物体的重量,问能称出多少种不同的重量. 现在给你两个正整数列表w和n, 列表w中的第i个元素w[i]表示第i个砝码的重量,列表n的第i个元素n[i]表示砝码i的最大数量.  i从0开始                   请你输出不同重量的种数.如:w=[1,2], n=[2,1], 则输出5(分析:共有五种重量:0,1,2,3,4) 解题 参考智力题砝码称重

蓝桥杯——说好的进阶之砝码称重(贪心算法)

5个砝码 用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量. 如果只有5个砝码,重量分别是1,3,9,27,81.则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中). 本题目要求编程实现:对用户给定的重量,给出砝码组合方案. 例如: 用户输入: 5 程序输出: 9-3-1 用户输入: 19 程序输出: 27-9+1 要求程序输出的组合总是大数在前小数在后. 可以假设用户的输入的数字符合范围1~121. public static void main(String

51nod 1449 砝码称重 (进制思想)

1449 砝码称重 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 现在有好多种砝码,他们的重量是 w0,w1,w2,...  每种各一个.问用这些砝码能不能表示一个重量为m的东西. 样例解释:可以将重物和3放到一个托盘中,9和1放到另外一个托盘中. Input 单组测试数据. 第一行有两个整数w,m (2 ≤ w ≤ 10^9, 1 ≤ m ≤ 10^9). Output 如果能,输出YES,否则输出NO.

J - 砝码称重 改自51nod1449

J - 砝码称重 Time Limit: 2000/1000 MS (Java/Others)      Memory Limit: 128000/64000 KB (Java/Others) Submit Status Problem Description 有一个物品和一些已知质量的砝码和天平,问能不能用这些砝码称出这个物品的重量(天平两边都可以放砝码) Input 多样例输入,样例数<=20000 对于每个样例: 第一行输入两个数n,m,表示砝码数量和重物质量,1 ≤ m ≤ 1018 第

wiki 2144 砝码称重 2 STL_map

前言       最近学习C#,不过好在当初考计算机二级学习过C++,刚上手没有对C#感到很恐惧.C#视频也看了几天 了,总感觉不总结一下心里没底,现在跟着我从头走进C#之旅吧.     C#是以后总面向对象的编程语言(OOP),C#是从C和C++派生出来的,主要用于开发可以运行在.NET平台 上的应用程序.随着.NET的发展,C#语言简单.现代.面向对象和类型安全显示了一定的优势.     下面我就介绍一些初学者不太理解的一些东西.   C#有以下突出的特点       (1)语法简洁.不允许

C程序设计的抽象思维-递归过程-砝码称重

[问题] 在狄更斯时代,商人们用砝码和天平来称量商品的重量,如果你只有几个砝码,就只能精确地称出一定的重量.例如,假定只有两个砝码:分别是1kg和3kg.只用1kg的砝码可以称出1kg重量的商品,只用3kg的砝码可以称出3kg重量的商品.1kg和3kg的砝码放在天平同一边可以称出4kg重量的商品,放在不同边可以称出2kg重量的商品.因此利用这两个砝码,我们可以称出重量分别为1.2.3.4kg的商品. 编写一个递归函数: bool IsMeasurable(int target, int weig