奇怪的比赛(Python,递归,状态压缩动态规划dp)

目录

  • 前言:
  • 题目:
  • 思路:
    • 递归:
      • 代码及详细注释:
    • 状态压缩dp:
      • 代码及详细注释:
  • 总结:

前言:

这道题原本是蓝桥上的题,现在搜不到了,网上关于此题的讲解更是寥寥无几,仅有的讲解也只是递归思想,python讲解和状态压缩dp的解决方法都没有,这里就带大家用状态压缩dp方法来解决此题。

题目:

大奖赛计分规则:
每位选手需要回答10个问题(其编号为1到10),越后面越有难度。答对的,当前分数翻倍;答错了,则扣掉与题号相同的分数(选手必须回答问题,不回答按错误处理)。每位选手的起步分都是10分,某获胜选手最终得分刚好是100分,请推断出哪个题目答对了,哪个题目答错了?(答对的记为1,答错的记为0,则10个题目的回答情况可用仅含1和0的串来表示)。任务是算出所有可能情况,每个答案占一行。(填空题)

输出:
0010110011
0111010000
1011010000

思路:

递归:

分析本题首先想到递归思想,从得分100逆推出初始分数为10的方案。
首先定义一个字符串

如果本题答对了,则总得分除2,字符串首位加1(因为是从第10题往前推,所以要逆序加)

如果本题答错了,则总得分加上本题的序号数,字符串首位加0

这里还有一个小细节,如果得分是奇数,则不能除2(只能答错)。

代码及详细注释:

def ScoreOut(qs, score, out):# 如果qs为0if qs == 0:# 如果score等于10if score == 10:print(out)  # 输出当前字符串outreturn out  # 返回当前字符串outelse:return ""  # 返回空字符串else:# 如果score为偶数if score % 2 == 0:# 递归调用函数,分别将score除以2并在开头添加字符"1",以及将score加上qs并在开头添加字符"O"return ScoreOut(qs - 1, score // 2, "1" + out) + ScoreOut(qs - 1, score + qs, "O" + out)else:# 如果score为奇数,只递归调用将score加上qs并在开头添加字符"O"return ScoreOut(qs - 1, score + qs, "O" + out)# 初始调用函数
ScoreOut(10, 100, "")

状态压缩dp:

什么是状态压缩

利用一串0/1数字(二进制数)来表示各个点的状态

这就要求使用状态压缩的对象的状态必须只有两种,0 或 1(如果有三种状态用三进制来表示也未尝不可)。

需要将状态数据实现为基本数据类型,比如 int,long 等,即状态压缩。比如说棋盘上的格子,放棋子或者不放;硬币的正面或反面;题目的对或错等。

状态压缩要求状态数据中的单元个数不能太大,比如用 int 来表示一个状态的时候,状态的单元个数不能超过 32(32位CPU),所以题目一般都是至少有一维的数据范围很小。

当然Python不需要考虑数的大小是否受限。

分析本题,上面用递归讲解过本题,有递归就用动态规划来解决,众所周知,递归很好理解和书写,但是递归的时间复杂度都不低,会有大量冗余计算。像本题中

如图

在这里插入图片描述
会出现大量相同得分情况,这就需要借助动态规划来处理重复计算了。

动态规划五部曲来分析

  1. 确定dp数组的定义

对于数组dp[i] :

下标表示10道题目的对错状态,dp[i]表示对应得分

下标 i 的二进制数表示对错状态,如 i = 2 时 i 的二进制数为 10 ,此时10(第1题答错,之后的提还没有做)(二进制数)的得分为多少,i = 7 时,i的二进制数为111,此时(第1题答对,第2题答对,之后的题还没有做)的得分为多少
特别注意!!! 这里首位的1(二进制后的数)没有实际含义,不表示题目对错,这个在下面会讲解

题目中有10道题,总共的有2 ** 10 - 1 种可能种情况(可能的情况用2进制计算就可以得出,如从000000000到111111111的可能数)

对于0000000000(这些都是10个数,不用挨个数了),二进制是这么表示,但10进制中,这个数就是0,

要想这个二进制数有意义,最前面就要加个1,否则无论有几个0,都表示0这个数,所以我们在定义dp数组长度的时候,不能为2 ** 10 而是为 2 ** 11(因为二进制1000000000(1后面10个0)的10进制数为 2 ** 11)

大家之前做题接触的二进制情况肯定不多,所以这里会稍微有点绕。这里主要理解前面自定义的1就好,跟补码的符号位有异曲同工之妙,只不过这里仅仅用来补位。

  1. dp数组的递推公式

状态压缩dp的递推公式还跟别的动规的递推公式不太一样,这里需要用到位运算符

这里简单讲解一下位运算符:

<< : 表示运算数的各二进制位全部左移若干位,低位补0
7 << 1 = 14, 因为7的二进制数为111,左移一位后为1110,1110的十进制数为14

右移跟左移同理。

还有python的二进制数可以用bin()函数来求,如bin(7) = 0b111,0b表示二进制,bin(7)的类型为字符串型。但是直接写0b111 就表示整型

因为第二道题的得分是由第一道题的得分算出来的,如

dp[0b1 << 1] = dp[0b1] - 1          #   dp[0b10]即dp[2]
dp[(0b1 << 1) +1] = dp[0b1] * 2      #  dp[0b11]即dp[3]

对于第cur道题,

如果答错dp[i << 1] = dp[i] - cur
如果答对dp[(i << 1) + 1] = dp[i] * 2

在推导递推公式的时候如果不太清楚,就看看dp数组的定义,切记第一个1无实义

  1. dp数组如何初始化

因为第一个1无实义,所以

dp[0b1] = 10  # dp[1]初始化得分为10
  1. dp数组遍历顺序

毫无疑问,题是从前往后答的,dp数组也是从左往右推

  1. 打印dp数组

画的有点丑,下标最好写成二进制形式。
在这里插入图片描述

求出dp数组后就把得分为100且10道题全都做了的结果输出就行。比较简单,有很多种方法,就不细说了。

代码及详细注释:

import math# 初始化一个长度为2^11的数组,初始值为0
dp = [0] * 2 ** 11
dp[1] = 10  # dp[1]初始化得分为10
# dp[0b1 <<1] = dp[0b1] - 1             dp[0b10]即dp[2]
# dp[(0b1 <<1) +1] = dp[0b1] * 2        dp[0b11]即dp[3]maxscore = 160  # 最大分数为160(因为160怎么减题目序号都到不了100,也可以设170等等)
for i in range(1, 2 ** 10):if dp[i] == -1:continueelse:cur = int(math.log2(i << 1))  # 计算准备做的题目序号,因为第一个1无实际意义,1之后的数才表示题的对错if dp[i] - cur <= 0:dp[i << 1] = -1else:dp[i << 1] = dp[i] - curif dp[i] * 2 >= maxscore:dp[(i << 1) + 1] = -1else:dp[(i << 1) + 1] = dp[i] * 2result = []
while True:if 100 in dp:index = dp.index(100)  # 找到值为100的索引dp[index] = 0if len(bin(index)) == 13:result.append(bin(index))  # 将长度为13(10道题都做完了,头三位为0b1)的二进制数添加到结果列表中else:breakfor res in result:print(res[3:])  # 输出结果列表中每个元素的第3位之后的内容

总结:

状态压缩dp还是比较难的,但把dp的定义吃透就比较好理解了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/749255.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

echo,date,bc命令详解

文章目录 echo&#xff0c;date&#xff0c;bc命令详解echo(输出文本)date(显示日期的命令)date命令的--date选项date命令 bc(高精度计算器) echo&#xff0c;date&#xff0c;bc命令详解 echo(输出文本) echo命令是一个常用的Shell命令&#xff0c;用于在终端上输出文本。它…

Python爬虫:原理与实战

引言 在当今的信息时代&#xff0c;互联网上的数据如同浩瀚的海洋&#xff0c;充满了无尽的宝藏。Python爬虫作为一种高效的数据抓取工具&#xff0c;能够帮助我们轻松地获取这些数据&#xff0c;并进行后续的分析和处理。本文将深入探讨Python爬虫的原理&#xff0c;并结合实战…

企业的数据治理如何评估

在数字化时代&#xff0c;企业对数据的管理和利用已经成为了一个关键的竞争力。通过有效的数据治理&#xff0c;企业能够更好地理解、分析和应用数据&#xff0c;从而提升决策的准确性和效率。然而&#xff0c;要构建一个高效可靠的数据管理体系&#xff0c;并进行评估&#xf…

acp认证考试费用多少?

2023年阿里云大数据ACP认证费用为1200元。请注意&#xff0c;此费用涵盖一次考试机会&#xff0c;若未能通过考试&#xff0c;需要重新缴费才能再次参加考试。 二、考试方式与地点 阿里云大数据ACP认证考试采用线上或线下考试方式。无论你身在何处&#xff0c;都可以方便地参…

Docker环境快速搭建RocketMq

window上面安装&#xff1a; 1.Namesrv docker pull rocketmqinc/rocketmq创建C:/docker/rocketmq/data/namesrv/logs:/root/logs C:/docker/rocketmq/data/namesrv/store:/root/store 目录 namesrv: docker run -d --restartalways --name rmqnamesrv -p 9876:9876 -v C:/do…

kkview远程控制: 内网远程桌面控制软件

内网远程桌面控制软件&#xff1a;高效、安全的远程管理方案 在信息技术日新月异的今天&#xff0c;内网远程桌面控制软件已成为许多企业和个人用户不可或缺的工具。这类软件允许用户通过内部网络&#xff0c;实现对其他计算机的远程访问和控制&#xff0c;从而大大提高工作效…

LLM大语言模型(七):部署ChatGLM3-6B并提供HTTP server能力

目录 HighLight 部署ChatGLM3-6B并开启HTTP server能力 下载embedding模型bge-large-zh-v1.5 HTTP接口问答示例 LLM讲了个尴尬的笑话~ HighLight 将LLM服务化&#xff08;如提供HTTP server能力&#xff09;&#xff0c;才能在其上构建自己的应用。 部署ChatGLM3-6B并开启…

[Windows] Win11 常用快捷键

文章目录 &#x1f680; [Windows] Win11 常用快捷键&#x1f310; Windows 操作系统&#x1f525; Windows 11 &#x1f310; Windows 11 快捷键概览&#x1f525; 基本快捷键&#x1f525; 窗口快捷键&#x1f525; 功能快捷键 &#x1f4dd; 小结 &#x1f680; [Windows] W…

工欲善其事,必先利其器,Markdown和Mermaid的梦幻联动(2)

该文章Github地址&#xff1a;https://github.com/AntonyCheng/typora-notes/tree/master/chapter03-mermaid 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文…

C#编程语言在软件开发中的深度应用与实践

C#编程语言在软件开发中的深度应用与实践 一、引言 C#是一种现代、通用、面向对象的编程语言&#xff0c;由微软公司开发&#xff0c;并作为.NET框架的主要编程语言。它广泛应用于桌面应用程序、游戏开发、Web服务和云计算等多个领域。本文将探讨使用C#进行软件开发的深层次思路…

QT6 界面中嵌入第三方程序中的窗口

本文描述QT6 界面中嵌入第三方程序中的窗口。 第三方程序也是用QT6编写。 QT的编译器版本都为QT6.2.4 MSVC2019 64 bit 第三方程序为QT写的能调试成功。但不是QT写的还不可以。 使用场景:将软件分成几个模块&#xff0c;多人写或者一个人先后写。 1.头文件 #ifndef PAREN…

数字航海与网络深渊:探索出海策略中的技术维度

在这个数字化加速的时代&#xff0c;"出海"已经成为企业寻求新机遇、拓展全球视野的关键行动。而在这一进程中&#xff0c;SOCKS5代理、代理IP、跨界电商、游戏技术以及网络安全构成了出海航程中的核心技术舵手。这些技术不仅是航行工具&#xff0c;更是深渊中的指南…

ChatGPT 遇到对手:Anthropic Claude 语言模型的崛起

ChatGPT 遇到对手&#xff1a;Anthropic Claude 语言模型的崛起 。 这个巨大的上下文容量使 Claude 2.1 能够处理更大的数据体。用户可以提供复杂的代码库、详细的财务报告或广泛的作品作为提示。然后 Claude 可以连贯地总结长文本&#xff0c;基于文档进行彻底的问答&#x…

“技多不压身”是什么意思?看完这篇文章你会明白:有了手艺,走遍天下都不怕!

“技多不压身”是什么意思&#xff1f;看完这篇文章你会明白&#xff1a;有了手艺&#xff0c;走遍天下都不怕&#xff01; 咱们的老祖宗流传一句话&#xff1a;“一招鲜&#xff0c;吃遍天。”这话说得直白&#xff0c;却道出了学一门手艺或技术对于人生的重要性。“李秘书讲…

系统设计学习(四)海量数据

十一&#xff0c;百亿数据中找中位数 桶/计数排序思想 根据数据的特征&#xff0c;比如数据落在某个固定范围内&#xff0c;可以使用桶排序或计数排序的思想。通过统计每个桶内元素的数量&#xff0c;我们可以确定中位数所在的桶&#xff0c;然后在该桶内使用更精确的方法计算中…

使用Loadrunner进行性能测试

一、确定性能测试的范围、要求、配置、工具等 明确测试的系统&#xff1a; 本文档主要指的是web应用。 明确测试要求&#xff1a; 用户提出性能测试&#xff0c;例如&#xff0c;网站首页页面响应时间在3S之内&#xff0c;主要的业务操作时间小于10s&#xff0c;支持300用户在…

Android Studio实现内容丰富的安卓宠物用品商店管理系统

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动。 项目编号128 1.开发环境android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.系统公告 3.宠物社区&#xff08;可发布宠物帖子&#…

2024.3.12-408学习笔记-C-C++语法中的引用和布尔类型

1、引用& #include <stdio.h>void modify_pointer(int* &p1, int* q1) {p1 q1; }int main() {int* p NULL;int i 10;int* q &i;modify_pointer(p, q);printf("after modify_pointer *p %d\n", *p);//after modify_pointer *p 10return 0; }…

this是什么?为什么要改变this?怎么改变 this 指向?

目录 this 是什么&#xff1f; 箭头函数中的 this 为什么要改变 this 指向&#xff1f; 改变 this 指向的三种方法 call(无数个参数) apply(两个参数) bind(无数个参数) this 是什么&#xff1f; 在对象方法中&#xff0c;this 指的是所有者对象&#xff08;方法的拥有者…

提升口才表达能力的重要性与途径

提升口才表达能力的重要性与途径 口才表达能力&#xff0c;即一个人通过口头语言准确、流畅、生动地传达思想、情感和观点的能力&#xff0c;是现代社会中不可或缺的一项基本技能。无论是在职场沟通、人际交往还是公共场合发言&#xff0c;优秀的口才表达能力都能为我们带来诸…