洛谷蓝桥真题2023 填空问题——有奖问答

最近刷洛谷,备战蓝桥杯,学到动态规划,感觉有些费解,遂写下自己的第一篇博客记录自己的思考过程,也督促自己学习。

# [蓝桥杯 2023 省 A] 填空问题

## 题目描述

## B. 有奖问答

小蓝正在参与一个现场问答的节目。活动中一共有 $30$ 道题目,每题只有答对和答错两种情况,每答对一题得 $10$ 分,答错一题分数归零。

小蓝可以在任意时刻结束答题并获得目前分数对应的奖项,之后不能再答任何题目。最高奖项需要 $100$ 分,所以到达 $100$ 分时小蓝会直接停止答题。

已知小蓝最终实际获得了 $70$ 分对应的奖项,请问小蓝所有可能的答题情况有多少种?

## 提示

难度: 困难   标签: 2023, 省赛, 动态规划, DP

第十四届蓝桥杯大赛软件赛省赛 C/C++ 大学 A 组 A-B

思路:首先初学者小白最容易想到的就是模拟,暴力穷举每一中可能性(2的30次幂) 

明显太费时间,不可取

因为答题是累加分数,答对+10,答错了归零。(注意分数等于100时会退出答题)

因此想到动态规划算法,即答完第 i 道题时的得分情况可以由第i - 1的情况推导出来

首先确定dp数组,初学可以用二维,方便思考

具体如下:

                确定dp[i][j]的含义:答完前 i 道题目时得分为 j 的情况总数

                确定初始条件:dp[1][10] = 1; dp[1][0] = 1;//所谓初始条件,就是答完第一题的得分情况

                1.第 i 题答对:即dp[i][j] = dp[i-1][j-10];//因为如果题目答对,当前得分情况就是上一道题答完时的情况总数

                2.第 i 题答错:即dp[i][0] = i-1题答完后各种得分的情况数总和,因为第i题答错了,则答完i - 1题时不管得分多少,都会清零。所以累加dp[i-1][ ]

思路总结完毕,下面写代码(本人比较懒,都用万能头加std)

#include<bits/stdc++.h>
using namespace std;
int dp[31][101];//空间开在main函数外,防止比赛内存溢出报错 
int main()
{
    dp[1][10] = 1;
    dp[1][0] = 1;
    long long ans = 0;
    for(int i = 2; i <= 30; i++)//外层循环遍历题目(注意要从第二题开始,因为第一题已经定义了,而且从i=1开始会导致i-1为0,这种情况不存在),内层循环遍历得分情况 
    {
        for(int j = 0; j <= 90; j = j + 10)//为什么不遍历到100分呢,因为题目说100分就停止答题了,所以不需要
        {
            if(j != 0)//如果第i题答对了
            {
                dp[i][j] = dp[i-1][j-10]; 
                
            }
            else if(j == 0)//如果第i题答错了,那么当前情况数(当前就得0分了)就是答完上一道题后所有得分的情况总和 
            {
                //我们用循环累加
                for(int k = 0; k <= 90; k = k + 10)
                {
                    dp[i][0] += dp[i-1][k];
                } 
            }
        }
        
        
        ans = ans + dp[i][70];
         //为什么不在循环外面直接输出dp[30][70]呢?因为题目说过可以在任意时刻结束答题,所以我们ans加上在当前题目答完之后70分的情况数 
    }//如果最后输出dp[30][70],那表示的是答完30道题之后得70分的情况,但是我们有可能没有答完30题就已经得到70分了 
    cout << ans;
    return 0; 
}

  • 43
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值