问题描述:

小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子。每种蒸笼都有非常多笼,可以认为是无限笼。每当有顾客想买X个包子,卖包子的大叔就会迅速选出若干笼包子来,使得这若干笼中恰好一共有X个包子。比如一共有3种蒸笼,分别能放3、4和5个包子。当顾客想买11个包子时,大叔就会选2笼3个的再加1笼5个的(也可能选出1笼3个的再加2笼4个的)。当然有时包子大叔无论如何也凑不出顾客想买的数量。比如一共有3种蒸笼,分别能放4、5和6个包子。而顾客想买7个包子时,大叔就凑不出来了。小明想知道一共有多少种数目是包子大叔凑不出来的。

【输入】

第一行包含一个整数N。(1 <= N <= 100)

以下N行每行包含一个整数Ai。(1 <= Ai <= 100)

【输出】一个整数代表答案。如果凑不出的数目有无限多个,输出INF。

【输入输出范例】

输入:

2

4

5

程序应该输出:

6

再例如,

输入:

2

4

6

程序应该输出:

INF

解题思路:

此题是主要是根据蒸笼的种类来组合出能做多少个包子,简单来说将n种数进行组合,每种数个数不限(其实1w差不多了),找到有哪些数是无法组合的,只用统计不能组合出的个数;此题难点就在每种数能拿的个数没有限制,比如(给出3种数:4,5,6)能组合的结果:每个数的倍数,每两个数相加的倍数,三个数相加的倍数,单取数字4,i个再加上5,6,似乎可以组合出很多很多个,穷举不太现实,所以此题用DP来做比较合适,DP主要是解决记住i个数字+其他数字j个 ( 比如:4 * i  +  5 * j ( j = 1,2,3...n) ),也节省了当出现相同的数时有不同组合结果的时间 (20 = 4 * 5 or 5 * 4),有点像完全背包,但不完全是,因为这题不是求最优解(价值最大之类的),而是统计不能组成的数有多少,比背包问题简单了一些。

算法设计:

  • 用一个dp[ ]来判断这个数能不能组合成,这个数组大小可以给1w,更多也行, 这个范围是求出1~上限,不能组合出的数的个数(我只统计了1~1w的,可以近似理解为无穷大)。
  • 数组dp[10000] = { 0 },0代表不能组成,1表示能组合(其他数都可以),再用一个a[ ]数组存你的原始数(比如你的4,5,6),表达式:( dp[ j  -  a[ i ] ] == 1 ), j = 1,2,3...n, 相当于用两层循环(最外层循环原始数,内层遍历所有数),当然先把dp[ 0 ] = 1,自己本身肯定能组成,遍历的时候把符合条件的数进行标记,dp[ j ] = 1,这样就能统计出每个数要不同个数时的结果。
  • 还要解决一个判断条件,判断是否有无限种不可以组合的情况,从例子中看出:当原始数都是偶数,或者原始数全为某一个数的倍数关系情况下,就有无限种不可能组合出的数。

 代码:

 #include<stdio.h>
#include<string.h>
#define maxSize 10000
int dp[maxSize];//初始化dp数组,大小自己定(越大越接近无穷)
//判断函数
bool judge(int x, int y)
{
//判断是否全为偶数
//或者候选数全为某一个倍数关系
int t;
while (y > )
{
t = x % y;
x = y;
y = t;
}
if (x == )
return true;
return false;
}
void count(int a[], int n)
{
int res, mark, i, j;
res = ;//计数
mark = ;//判断是否无限的变量
memset(dp, , sizeof(dp));//将数组dp的数全部置为0,不用memset也行,直接dp[10000] = { 0 }
//也对memset主要适用于动态分配内存后的清0手段,其他情况效果差不多
for (i = ; i <= n; i++)
{
scanf("%d", &a[i]);
}
for (i = ; i <= n; i++)
{
for (j = ; j <= n; j++)
{
if (judge(a[i], a[j]))//每次只能判断两个,所以二层循环遍历所有情况
{
mark = ;
break;
}
}
if (mark == )
break;//只要有一个符合jugde函数就能数出组合的数量
}
if (mark != )
{
printf("INF\n");
return;
}
dp[] = ;//第一个表示候选数的本身,故能组合自己
for (i = ; i <= n; i++)
for (j = ; j < maxSize; j++)
{
//记忆型存储,即时保存之前能组合的数
//输入不分大小,但是要有一定顺序
if (a[i] > j)
continue;//比自己本身还小的数,一定组合不出结果
if (dp[j - a[i]] == )
dp[j] = ;
}
for (i = ; i < maxSize; i++)
{
if (dp[i] != )
res++;//统计不能组合出来数的数量
}
printf("%d\n", res);
}
int main()
{
//小明制作包子问题,蒸笼种类n,每种蒸笼x个包子,统计有多少个包子组合不出来
int a[], n;//数组a可以动态分配
scanf("%d", &n);
count(a, n);
return ;
}

时间复杂度:O(n * maxSize)

如果有更优化的算法,可以指出来,谢谢

包子凑数(dp思想)的更多相关文章

  1. 包子凑数(dp 0-1、完全背包)【背包问题】

    包子凑数(蓝桥杯) 感谢:@ Statusrank 题目链接(点击) 题目描述 小明几乎每天早晨都会在一家包子铺吃早餐.他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子.每种蒸笼都有非常多 ...

  2. c++_包子凑数

    标题:包子凑数 小明几乎每天早晨都会在一家包子铺吃早餐.他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子.每种蒸笼都有非常多笼,可以认为是无限笼. 每当有顾客想买X个包子,卖包子的大叔就会 ...

  3. Java实现第八届蓝桥杯包子凑数

    包子凑数 题目描述 小明几乎每天早晨都会在一家包子铺吃早餐.他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子.每种蒸笼都有非常多笼,可以认为是无限笼. 每当有顾客想买X个包子,卖包子的大叔 ...

  4. 到底什么是dp思想(内含大量经典例题,附带详细解析)

    期末了,通过写博客的方式复习一下dp,把自己理解的dp思想通过样例全部说出来 说说我所理解的dp思想 dp一般用于解决多阶段决策问题,即每个阶段都要做一个决策,全部的决策是一个决策序列,要你求一个 最 ...

  5. hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

    Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  6. DP思想在斐波那契数列递归求解中的应用

    斐波那契数列:1, 1, 2, 3, 5, 8, 13,...,即 f(n) = f(n-1) + f(n-2). 求第n个数的值. 方法一:迭代 public static int iterativ ...

  7. hdu 4612 Warm up 双连通+树形dp思想

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total S ...

  8. DP思想笔记

    一.思想 DP也是把复杂的问题分解为许多子问题,与分治法不同的是,分治法的各个子问题互相之间没有联系,而动态规划却有.前一个子问题的结果与下一步的子问题的结果是什么有关系.这就决定了DP算法肯定有一个 ...

  9. CodeForces5E 环转链,dp思想

    http://codeforces.com/problemset/problem/5/E 众所周知,在很久以前,在今天的 Berland 地区,居住着 Bindian 部落.他们的首都被 n 座山所环 ...

随机推荐

  1. Docker 实现的 redis 主从

    计划用 Docker 实现 Redis 的主从,简单主从而已.主的名称叫 redis-master 一步步来. 先新建个Dockerfile ,从alpine 开始,比较简单. FROM alpine ...

  2. C#中利用LINQ to XML与反射把任意类型的泛型集合转换成XML格式字符串

    在工作中,如果需要跟XML打交道,难免会遇到需要把一个类型集合转换成XML格式的情况.之前的方法比较笨拙,需要给不同的类型,各自写一个转换的函数.但是后来接触反射后,就知道可以利用反射去读取一个类型的 ...

  3. JS实现windows.open打开窗口并居中

    function openWin() {            var url='Add.aspx';                             //转向网页的地址;           ...

  4. lnmp 多站点配置负载均衡

    1.虚拟机安装3个centos 2.三台服务器IP: 192.168.191.129(主)192.168.191.130192.168.191.131 3.分别在3台服务器的vhost目录下新建配置文 ...

  5. 9.29学习的js基础

    js基础 1.三种js引入方式    a).<input type="button" value="点击事件" onClick="documen ...

  6. NIOS II下基于中断的UART接收和发送设计示例代码

    #include "sys/alt_stdio.h" #include "altera_avalon_uart_regs.h" #include "s ...

  7. BZOJ 3884 上帝与集合的正确用法(扩展欧拉定理)

    Description   根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做“元”. 第二天, 上帝创造了一个新的元素,称作“α”.“α”被定义为“ ...

  8. ORM,Entity Framework介绍以及其所包含的基础架构介绍

    一:entity framework 6.0 ORM (实体关系模型) O: Domain Object 领域模型 R: Relational Database 关系型数据库 M: Mapping 映 ...

  9. 在.net Core中使用StackExchange.Redis 2.0

    StackExchange.Redis 2.0做了大量的改进包括使用了高性能的IO库System.IO.Pipelines来提升性能以及解决Timeouts问题, 但是在.net Core2.2之前为 ...

  10. ASP.NETMVC4 分页组合查询解决方法

    本人新手刚在webform转到mvc   像linq  ef啥的,都是不会的不行不行的,不会就问群友,找资料 今天本屌遇到了一个分页组合查询的问题,解决了2个小时,把代码共享给大家 话不多话,直接上代 ...