题意:

演唱会门票售票处,那里最开始没有零钱。每一张门票是50元,人们只会拿着100元和50元去买票,有n个人是拿着50元买票,m个人拿着100元去买票。

n+m个人按照某个顺序按序买票,如果一个人拿着100元买票,而你没有零钱去找给他,那么买票结束。

题目问你,这n+m个人按照某个顺序按序买票,中间买票没有暂停的排队方式有多少种

题解:

我们设dp[i][j]表示一共有i个人,其中有j个人拿着50元买票的有效排队方式

说一下转移方程:

如果第i个人准备在前i-1个人的排队方式基础上拿着50元去买票,那么dp[i][j]要加上dp[i-1][j-1]

如果第i个人准备在前i-1个人的排队方式基础上拿着100元去买票,那么dp[i][j]要加上dp[i-1][j]

这里要说一下,我们每一个dp[i][j]都是最优的,而不是背包dp一样,中间状态不是最优

可能有人会想,你这个转移方程能够保存这么多排队方式嘛?看着不像呀!

我们这里实例来模拟一下:n=3,m=1

初始化:dp[0][0]=1

dp[1][1]=dp[0][0]+dp[0][1]=1,为了保证排队方式有效,那么前面拿着50元的人,肯定要大于等于100元的人,所以dp[1][0]就不存在

dp[2][1]=dp[1][0]+dp[1][1]=1。dp[2][2]=dp[1][1]+dp[1][2]=1

dp[3][1]=dp[2][0]+dp[2][1]=1。dp[3][2]=dp[2][1]+dp[2][2]=2  作为第一个值大于1的数,我们肯定要详细解释一下他的意思

dp[3][2]由dp[2][1]转化来这一部分,也就代表了50 100 50这个排队序列

dp[3][2]由dp[2][2]转化来这一部分,也就代表了50 50 50这个排队序列

剩下的dp状态都这样,你会发现,它们的状态其实并没有发生缺失情况,它只是以数字形式传递下去

因为这样算的时候我们把所有人都看作一样的,所以我们的答案需要乘于n的阶乘和m的阶乘,也就相当于按照人进行全排列A1n和A1m

代码:

#include<bits/stdc++.h>
#define MAXN 1000
using namespace std;
char fac[201][MAXN];
char dp[201][201][1005];
char ans1[100005],ans2[1000005];
int n,m;
void BigNumMultiSmall(char *a, char *b, int mul)
{
//a表示结果,b表示被乘数,mul表示乘数
int i, j, len;
int a_int[2000] = { 0 }, b_int[1000] = { 0 };
len = strlen(b);
for (i = 0; i < len; i++)
b_int[i] = b[len - 1 - i] - '0';
for (i = 0; i<len; i++)
{
a_int[i] = a_int[i] + b_int[i] * mul;
if (a_int[i]>9)
{
a_int[i + 1] = a_int[i] / 10;
a_int[i] = a_int[i] % 10;
}
}
while (a_int[i])
{
a_int[i + 1] = a_int[i] / 10;
a_int[i] = a_int[i] % 10;
i++;
}
while (a_int[i - 1] == 0)
i--;
for (j = 0; j < i; j++)
a[j] = a_int[i - j - 1] + '0';
a[j] = '\0';
}
void BigMultiBig(char *a, char *b, char *c)
{
int i, j, len1, len2, len;
int a_int[2010] = { 0 }, b_int[1000] = { 0 }, c_int[1000] = { 0 };
len1 = strlen(b);
for (i = len1 - 1; i >= 0; i--)
b_int[len1 - i - 1] = b[i] - '0';
len2 = strlen(c);
for (i = len2 - 1; i >= 0; i--)
c_int[len2 - i - 1] = c[i] - '0';
len = len1 + len2;
for (i = 0; i < len1; i++)
for (j = 0; j < len2; j++)
a_int[i + j] += b_int[i] * c_int[j];
for (i = 0; i<len; i++)
if (a_int[i]>9)
{
a_int[i + 1] += a_int[i] / 10;
a_int[i] = a_int[i] % 10;
}
while (a_int[len - 1] == 0)
len--;
for (i = 0; i < len; i++)
a[i] = a_int[len - i - 1] + '0';
a[i] = '\0';
if (strlen(a) == 0)
strcpy(a, "0");
}
void BigAddBig(char *a, char *b, char *c)
{
//a表示结果,b,c位加数
int a_int[1005] = { 0 }, b_int[1005] = { 0 }, c_int[1005] = { 0 };
int len1, len2, len, i;
len1 = strlen(b);
len2 = strlen(c);
for (i = 0; i < len1; i++)
b_int[i] = b[len1 - 1 - i] - '0';
for (i = 0; i<len2; i++)
c_int[i] = c[len2 - 1 - i] - '0';
len = len1>len2 ? len1 : len2;
for (i = 0; i<len; i++)
{
a_int[i] += b_int[i] + c_int[i];
if (a_int[i]>9)
{
a_int[i + 1] = a_int[i] / 10;
a_int[i] = a_int[i] % 10;
}
}
if (a_int[i] != 0)
len++;
while (!a_int[len - 1])
len--;
for (i = 0; i < len; i++)
a[i] = a_int[len - 1 - i] + '0';
a[i] = '\0';
}
void init() //求前缀乘
{
fac[0][0]='1';fac[1][0]='1';
for(int i=2;i<=200;i++)
{
BigNumMultiSmall(fac[i],fac[i-1],i);
// printf("%s\n",fac[i]);
}
}
void solve()
{
//dp[1][0][0]='1';
dp[0][0][0]='1';
//dp[0][0][1]='1';
for(int i=1;i<=210;i++) //一共有i个人
{
for(int j=1;j<=min(i,100);j++) //有j个人用50元
{
if(i-j>j)
{
continue;
}
BigAddBig(dp[i][j],dp[i-1][j-1],dp[i-1][j]); }
}
//printf("%s\n",dp[3][2]);
}
int main()
{
init();
solve();
int t=1;
while(scanf("%d %d",&n,&m))
{
if((!n)&&(!m))
{
break;
}
BigMultiBig(ans1,fac[n],dp[n+m][n]);
BigMultiBig(ans2,ans1,fac[m]);
printf("Test #%d:\n",t++);
printf("%s\n",ans2);
}
}

Buy the Ticket HDU - 1133 大数dp的更多相关文章

  1. Buy the Ticket HDU 1133 递推+大数

    题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=1133 题目大意: 有m+n个人去买电影票,每张电影票50元,  m个人是只有50元一张的,  n个人 ...

  2. Buy the Ticket HDU 1133 卡特兰数应用+Java大数

    Problem Description The "Harry Potter and the Goblet of Fire" will be on show in the next ...

  3. Buy the Ticket HDU 1133

    传送门 [http://acm.hdu.edu.cn/showproblem.php?pid=1133] 题目描述和分析 代码 #include<iostream> #include< ...

  4. 【hdoj_1133】Buy the Ticket(卡特兰数+大数)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1133 题目的意思是,m个人只有50元钱,n个人只有100元整钱,票价50元/人.现在售票厅没钱,只有50元 ...

  5. hdu 1502 大数dp

    对于每一个dp的问题 从其最优解的结构(分哪几种形式或者情况)入手 然后分析状态 这样就比较好找出状态转方程这里数据结构的选择很简单 顺序数组就可以 填充的方式顺序填充就可以 然后这道题目卡了我大数. ...

  6. HDU 1133 Buy the Ticket (数学、大数阶乘)

    Buy the Ticket Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  7. hdu 1133 Buy the Ticket (大数+递推)

    Buy the Ticket Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  8. 【HDU 1133】 Buy the Ticket (卡特兰数)

    Buy the Ticket Problem Description The "Harry Potter and the Goblet of Fire" will be on sh ...

  9. hdu 1133 Buy the Ticket(Catalan)

    Buy the Ticket Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

随机推荐

  1. oracle range分区表已经有了MAXVALUE 分区,如何添加分区?要不能删除MAXVALUE分区里的数据,不影响在线应用。

    来做个实验说明该问题:1.创建个分区表SQL> create table p_range_test 2 (id number,name varchar2(100)) 3 partition by ...

  2. es6 Array.from + new Set 去重复

    // es6 set数据结构 生成一个数据集 里面的元素是唯一的 const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]); // items 是个对象 item ...

  3. 如何实现CentOS服务器的扩容??

    Linux的硬盘识别: 一般使用"fdisk -l"命令可以列出系统中当前连接的硬盘 设备和分区信息.新硬盘没有分区信息,则只显示硬盘大小信息. 1.关闭服务器加上新硬盘 2.启动 ...

  4. ssl证书与java keytool工具

    ssl协议 SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安 ...

  5. 【Docker】Docker概述、理解docker的集装箱、标准化、隔离的思想、 docker出现解决了什么问题

    整理一下 慕课网 第一个docker化的java应用 Docker环境下的前后端分离项目部署与运维 课程时所做的笔记 Docker概述 docker - https://www.docker.com/ ...

  6. kubernets之Replication Controller

    一  Replication Controller的介绍      pod可能会由于各种原因消失和多出来,例如node节点去除集群或者人为的手工创建,所以为了方便和管理pod的数量,k8s里面 的另外 ...

  7. java 利用异或^进行加密

    package com.zcj.eg001; import java.nio.charset.Charset; import org.junit.Test; public class Encrypti ...

  8. 微信小程序腾讯地图SDK使用方法

    一.本篇文章主要知识点有以下几种: 1.授权当前位置 2.map组件的使用 3.腾讯地图逆地址解析 4.坐标系的转化 二.效果如下: 三.WXML代码 <map id="map&quo ...

  9. centos&linux

    who am i 查看是哪一个用户 init 0关机 ifconfig用于配置网络或显示当前网络接口的状态 eth0是网卡的名字 第一行:flags后面的up指的是网卡处于运行状态,running连接 ...

  10. CSS奇思妙想 -- 使用 CSS 创造艺术

    本文属于 CSS 绘图技巧其中一篇.之前有过一篇:在 CSS 中使用三角函数绘制曲线图形及展示动画 想写一篇关于 CSS 创造艺术的文章已久,本文主要介绍如何借助 CSS-doodle ,利用 CSS ...