标题:李白打酒

话说大诗人李白,一生好饮。幸好他从不开车。

一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:

无事街上走,提壶去打酒。

逢店加一倍,遇花喝一斗。

这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。

请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。

注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容。

答案:14

先提供两种用枚举方式来解决此问题的方法,前面14个格子要摆放的是0,1(用0标识花,1标识店)

方案一,用0,1把前14个格子按照字典序打印出来,但要保证其0,1的总数小于规定总数。然后模拟这个过程。

代码:

 /*方法1*/#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 20
using namespace std;
int num[MAXN],s=;//花记为 0,店记为 1
void dfs(int cur)
{
int n0=,n1=,i,j,c=;
bool flag=true;
if(cur==)
{
for(i=;i<=;i++)
{
c=num[i]==?c-:c*;
if(c==)
{
flag=false;
break;
}
}
if(flag==false)
return ;
else
{
if(c==)
{
s++;
for(i=;i<=;i++)
cout<<num[i]<<' ';
cout<<<<endl;
}
return ;
}
}
for(i=;i<=;i++)
{
if(i==)
{
for(j=;j<=cur-;j++)
{
if(num[j]==)
n0++;
}
if(n0<)
{
num[cur]=;
dfs(cur+);
num[cur]=-;
}
}
else
{
for(j=;j<=cur-;j++)
{
if(num[j]==)
n1++;
}
if(n1<)
{
num[cur]=;
dfs(cur+);
num[cur]=-;
} }
}
}
int main()
{
memset(num,-,sizeof(num));
dfs();
cout<<s<<endl;
return ;
}

方案二,我们其实只要将5个1填入前14个格子里,其实是 种方案,我们依旧可以用枚举的方式实现,依次去按字典序排列5个数(但必须是按递增的序列排列)选取的数字是从1-14里选择

代码:

 /*方法2*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 20
using namespace std;
int num[MAXN],ans[MAXN],s=;//花记为 0,店记为 1
void dfs(int cur,int k)
{
int ok,c=,i,j;
bool flag=true;
if(cur==)
{
memset(num,,sizeof(num));
for(i=;i<=;i++)
{
num[ans[i]]=;
}
for(i=;i<=;i++)
{
c=num[i]==?c-:c*;
if(c==)
{
flag=false;
break;
}
}
if(flag==false)
return ;
else
{
if(c==)
{
s++;
for(i=;i<=;i++)
cout<<num[i]<<' ';
cout<<<<endl;
}
return ;
}
}
for(i=k+;i<=;i++)
{
ok=;
for(j=;j<=cur-;j++)
{
if(ans[j]==i)
ok=;
}
if(ok)
{
ans[cur]=i;
dfs(cur+,i);
}
}
}
int main()
{
memset(ans,,sizeof(ans));
dfs(,);
cout<<s<<endl;
return ;
}

而递归的方式实现将变得更加简洁。

由于实现此过程的总数等于开头为a和开头为b的总和,再递归这两个决策,直到a==0&&b==0&&c==1结束。

代码:

 /*递归*/
#include<iostream>
using namespace std;
int sum=;
int f(int a,int b,int c){ // a:店的总数 b:花的总数减1 c:酒的初值
// 任何初始状况,都有两个可能:先遇到店,或者先遇到花
if(a>)
f(a-,b,c*); // 逢店加一倍
if(b>)
f(a,b-,c-); // 遇花喝一斗
if(a==&&b==&&c==) //这个是满足要求的终止条件。没有店剩下,还剩一朵花和一斗酒
sum=sum+;
return sum;
}
int main()
{
f(,,);
cout<<sum<<endl;
return ;
}

最新文章

  1. 第六代智能英特尔&#174; 酷睿™ 处理器图形 API 开发人员指南
  2. 【GWAS文献解读】疟原虫青蒿素抗药性的全基因组关联分析
  3. nis,nfs,pam小结
  4. GO语言数组和切片实例详解
  5. 使用MVC过滤器保存操作日志
  6. Asp.net MVC中Html.Partial, RenderPartial, Action,RenderAction 区别和用法
  7. 基于kickstart定制自动化安装的linux镜像系统
  8. eclipse java.lang.OutOfMemoryError: Java heap space
  9. iOS 导航栏颜色字体等的自定义
  10. bzoj1009
  11. LFS,编译自己的Linux系统 - 准备分区
  12. Appium+Python app自动化测试之脚本启动和停止Appium服务
  13. [HAOI 2005][BZOJ 1054] 移动玩具
  14. SQL Constraints
  15. 使用vmware提示无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件
  16. (转)C/C++ 程序设计员应聘常见 面试笔试 试题深入剖析
  17. 扫盲 -- What&#39;s MOOC ?
  18. 牛客网NOIP赛前集训营-提高组(第六场)B-选择题[背包]
  19. 如何使用FLASHGOT下载网页FLASH
  20. Eclipse开发Java程序入门,HelloWord

热门文章

  1. Linux下查看系统CPU个数、核心数、线程数
  2. java gc小结
  3. Spring源码学习(一)资源加载
  4. mongoDB之监控工具mongotop
  5. Java中Class.forName()的作用(转载)
  6. MVC入门——增
  7. iOS UI13_数据解析XML_,JSON
  8. 【BZOJ1042】[HAOI2008]硬币购物 容斥
  9. 【BZOJ2400】Spoj 839 Optimal Marks 最小割
  10. Linux就该这么学--命令集合5(用户与组管理命令)