蓝桥杯2022年第十三届省赛真题-李白打酒加强版(超详细解析)

//动态规划,迭代

//思路:循环遍历所有情况
//迭代每次分两种情况,要么打酒要么看花分两种考虑
//用a[0][0][2]=1标记为真+迭代
//从而实现在所有情况中给最终结果
//增加有效值.
//迭代时注意设置条件避免输入非法数据
//

#include <stdio.h>
#include <stdlib.h>
#define mod 1000000007
int main(int argc, char *argv[])
{
  //0斗没有意义,因为最后要看花,不可能有0斗遇店
  
  int n,m,i,j,p;//n酒m花
  int a[101][101][101];//根据题设最大来设大小,用三维数组
  a[0][0][2]=1;//初始状态
  //如果在迭代中往前推推不到这个数组的,就一定是非法情况
  //自然数组最终结果为0

  //设1时相当于考虑开始时酒有两斗的情况,只有开始遵循这点才能算一种可能,相当于标记
  scanf("%d%d",&n,&m);

  //题范围为100,三个循环10^(2*3)=10^6够用
  
  for(i=0;i<=n;i++)//打酒
  //打多少次酒情况的遍历
  {
//    for(int j=0;i<=m;j++)//你看又是条件青光眼,真的6
     for(int j=0;j<=m;j++)//花
     //看多少次花情况的遍历
    {
      for(p=0;p<=m;p++)//酒量//循环上限是m是因为酒量和看花次数要相等
      //酒量为多少次情况的遍历
      {
        //打酒还是看花每次循环都分两个分支讨论
        //合法的自然会返回给a[n][m][0]真值
        //不合法自然返回0。
        if(p%2==0&&p>0&&i>0)//打酒
        //因为还需要讨论不打酒的情况,即i=0时
        //0斗就不可能再加酒了
        {
          // a[i][j][p]=(a[i][j][p]%mod)+(a[i-1][j][p/2]%mod);
          a[i][j][p]+=(a[i-1][j][p/2]%mod);
          //这一次情况       上一次
          //迭代
        }
        if(j>0)//看花
        //1开始表示开始看花
        {
          //  a[i][j][p]=(a[i][j][p]%mod)+(a[i][j-1][p+1]%mod);
             a[i][j][p]+=(a[i][j-1][p+1]%mod);
             //这次情况      上次的
          

           //可以直接写+=,因为每次迭代最新的情况即空数组,
           //根本就不存在数据溢出,因此对空数组没必要取模,只用
           //对前面的数组取模即可
           //看一次花少一斗,符合逻辑连接之前的数组,相当于一条线,就为一种情况,
           //要清楚因为循环是递增的,所以左边是后面的情况,右边是前面的情况
           //如a[0][0][2],那么它看花就是a[0][1][1]
           //等于1是标记也是计数,只有一直传下来到达最终的a[n][m][0]就统计为一种情况
           //等于0说明开始时不是两斗酒

           //最典型的就是p%2==0,假如后面的数组为[1][0][3],推前面为[0][0][1.5]
           //这是不存在的,所以要舍弃,其他同理

           //迭代思想每次都要从前面找答案,随着循环变大才能推出后面的结果
           //因此正常思路也一定是左边是当前最大的结果,右边是前面的结果!
           //想获得最终的答案,那都是要在前面结果的基础才能得出的!

           //满足条件,才进行此次情况的访问,计算这一次的结果,
           //因此放在左边,
           //而要算出,就要使用迭代,就是同样要找前面的结果
           
           
        }
       
      }
    }
  }
  printf("%d",a[n][m][0]);
  //循环遵循从简单到复杂,优先循环最简单的情况最佳
  //多重循环就是为了讨论完所有情况,最后回到a[n][m][0]时
  //就返回之前积累的所有的情况。

  //遍历所有可能,无脑循环查找.不必担心合不合法,不合法自然只会+0
  //a[0][0][2]开始的迭代就已经是合法的前提了!

  //a[n][m][0]表示他一共遇到店 N次, 遇到花 M次。正好把酒喝光了。
  //按照题设操作

  return 0;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值