【算法每日一练]-动态规划(保姆级教程 篇14) #三倍经验 #散步 #异或和 #抽奖概率

目录

 今日知识点:

金字塔的正反dp两种方案,转移方程取决于dp的具体含义

取模实现循环走m步回到原点的方案

在统计上升子序列的时候使用最小结尾元素进行标记,一举两得

将亏本的概率转换各种情况的方案,然后统计亏本的情况的方案数烦求概率

三倍经验

散步

 异或和

抽奖概率 


三倍经验

思路:

首先不要考虑那么复杂,如果只是取数,但不考虑加倍的操作,那么就简单很多,只需要从下层想上层推导即可。保证每此都是最优解就行了。

这个时候f[i][j]从f[i-1][j]和f[i-1][j-1]中来。那么自然:

f[i][j]=max(f[i-1][j],f[i-1][j-1]) +a[i][j]。

然后我们再考虑要成3倍的情况,因为每个点可以对应是否有3倍的情况,而且这个消耗情况也要记录下来。所以需要开三维来表示。

设置f[i][j][k]表示在耗费次3倍操作下 且走到i,j对应的最优解。
 转移方程:

 f[i][j][l]=max(f[i-1][j][l],f[i-1][j-1][l])+a[i][j]; (当前数没有消耗次数)

 f[i][j][l]=max(f[i][j][l],max(f[i-1][j][l-1],f[i-1][j-1][l-1])+a[i][j]*3(当前数消耗次数了)
  最终需要在f[n][i][0~k]中找答案

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105,INF=-3e9;
int n,k;
ll a[N][N],f[N][N][N],ans=INF;
int main(){cin>>n>>k;for(int i=1;i<=n;i++)for(int j=0;j<=n;j++)for(int l=0;l<=k;l++)f[i][j][l]=INF;for(int i=1;i<=n;i++)for(int j=1;j<=i;j++){cin>>a[i][j];for(int l=0;l<=min(k,i);l++){if(l==0)f[i][j][l]=max(f[i-1][j][l],f[i-1][j-1][l])+a[i][j];else{f[i][j][l]=max(f[i-1][j][l],f[i-1][j-1][l])+a[i][j];f[i][j][l]=max(f[i][j][l],max(f[i-1][j][l-1],f[i-1][j-1][l-1])+a[i][j]*3);}}}for(int i=1;i<=n;i++)for(int l=0;l<=min(k,n);l++)ans=max(ans,f[n][i][l]);cout<<ans;
}

上面的是正向写法(也就是从上到下)。

当然也可以从下到上写:

 设置f[i][j][k]表示从i,j从开始消耗k次对应的最优解。

那么f[i-1][j-1]和f[i-1][j]就应该借此更新:(然后再拆成是否乘3倍,那就是4个式子)

            f[i-1][j-1][k]=max(f[i-1][j-1][k],f[i][j][k]+a[i-1][j-1]);
            f[i-1][j-1][k+1]=max(f[i-1][j-1][k+1],f[i][j][k]+a[i-1][j-1]*3);
            f[i-1][j][k]=max(f[i-1][j][k],f[i][j][k]+a[i-1][j]);
            f[i-1][j][k+1]=max(f[i-1][j][k+1],f[i][j][k]+a[i-1][j]*3);    

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans=-0x3f3f3f3f,f[110][110][110],a[110][110];
int n,m;
int main(){memset(f,-0x3f3f3f3f,sizeof(f));cin>>n>>m;for(int i=1;i<=n;i++)for(int j=1;j<=i;j++)cin>>a[i][j];for(int i=1;i<=n;i++){f[n][i][0]=a[n][i];f[n][i][1]=a[n][i]*3;}for(int i=n;i>=2;i--)for(int j=1;j<=i;j++)for(int k=0;k<=min(n-i+2,m);k++){f[i-1][j-1][k]=max(f[i-1][j-1][k],f[i][j][k]+a[i-1][j-1]);f[i-1][j-1][k+1]=max(f[i-1][j-1][k+1],f[i][j][k]+a[i-1][j-1]*3);f[i-1][j][k]=max(f[i-1][j][k],f[i][j][k]+a[i-1][j]);f[i-1][j][k+1]=max(f[i-1][j][k+1],f[i][j][k]+a[i-1][j]*3);	}for(int i=0;i<=min(n,m);i++){ans=max(f[1][1][i],ans);}cout<<ans;
}

 可以会有人有疑问:既然(i,j)可以到(i+1,j)和(i+1,j+1),为什么不是f[i][j]=max(f[i+1][j],f[i+1][j+1])这个式子呢?

上图是正确的更新路线,举个例子:f[3][2]只能被f[2][1]和f[2][2]更新,因为只有这两个点才能到f[3][2],所有才有了f[i][j]=max(f[i-1][j],f[i-1][j-1])这个式子。 

OK解释完了!

        

        

散步

思路:

 设置dp[i][j]表示已经走了i步,然后到达j。然后循环可以用取模实现,但是取模一定是0~n-1,所以需要进行映射。

转移方程:dp[i][j]=dp[i-1][(j+1)%n]+dp[i-1][(j-1+n)%n]

最终dp[m][0]就是答案。

#include <bits/stdc++.h>
using namespace std;
int dp[35][35],n,m;
int main(){cin>>n>>m;dp[0][0]=1;for(int i=1;i<=m;i++)for(int j=0;j<n;j++)dp[i][j]=dp[i-1][(j+1)%n]+dp[i-1][(j-1+n)%n];cout<<dp[m][0];
}

        

         

 异或和

给一个长n的序列a1,a2……an,寻找在a的所有递增子序列(可以为空)的异或和中出现的数。

输入:                    输出:

2                                 4

1 5                              0 1 4 5

思路:

题意就是统计异或和,不过是仅统计所有上升子序列的异或和,那么就在每次更新上升子序列的时候就打一次标记,用什么打标记,当然直接使用数组元素最方便。
所以:设置dp[i]表示异或和为i的满足题意的最小结尾元素。(里面存的是最小的结尾元素)
dp[j]<a[i]时候(i可以拼在j后面):更新dp[j^a[i]]=min(dp[j^a[i],a[i])(标记了那个新异或和出现了)
最后统计有哪些dp被使用过,就说明这些数是答案
 

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],dp[N];int main(){memset(dp,0x3f3f3f3f,sizeof(dp));dp[0]=0;cin>>n;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++)for(int j=0;j<=550;j++)if(dp[j]<a[i]) dp[j^a[i]]=min(dp[j^a[i]],a[i]);vector<int> ans;for(int i=0;i<=550;i++)if(dp[i]!=0x3f3f3f3f) ans.push_back(i);cout<<ans.size()<<'\n';for(int i:ans)cout<<i<<" ";}

        

        

抽奖概率 

有一个抽奖活动:抽一个2元,可能会抽出1,2,3,4元(概率相等)。

问抽n次,亏本的概率是多少(奖金小于本金)?纯赚超过一半本金的概率是多少

输入:2           输出:3/16(分数时候输出最简分数)

                                   3/16

思路:

直接求概率不太容易。而且还要最简分数,那么就转化乘求方案数就会具体很多。

设置dp[i][j]表示已经抽奖i次且拿到了总额为j的方案数.dp[i][j]=dp[i-1][j-1,2,3,4]即可。

最后的最简分数可以使用gcd函数完成。
 

#include <bits/stdc++.h>
using namespace std;
int dp[40][160],n;
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}int main(){cin>>n;dp[1][1]=dp[1][2]=dp[1][3]=dp[1][4]=1;for(int i=1;i<=n;i++)for(int j=i;j<=4*n;j++){for(int k=1;k<=4;k++)if(j>k) dp[i][j]+=dp[i-1][j-k];}int sum1=0,sum2=0,sum=1;for(int i=n;i<2*n;i++)sum1+=dp[n][i];for(int i=3*n+1;i<=4*n;i++)sum2+=dp[n][i];for(int i=1;i<=n;i++)sum*=4;int k=gcd(sum1,sum);cout<<sum1/k<<"/"<<sum/k<<'\n';k=gcd(sum2,sum);cout<<sum2/k<<"/"<<sum/k<<'\n';}

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

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

相关文章

数字孪生技术详解

在线工具推荐&#xff1a;3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 数字孪生技术正在迅速彻底改变企业的运营方式。借助数字孪生技术&#xff0c…

【Nginx】在线安装与离线安装

目录 1、下载nginx news 1.2、 安装包 2、 在线安装 第一步&#xff0c;安装pcre 第二步&#xff0c;安装openssl 、zlib 、 gcc 依赖 第三步&#xff0c;安装nginx 第四步&#xff0c;关闭防火墙&#xff0c;访问nginx ​编辑 3、 离线安装 第一步 安装pcre 第二步…

【KingbaseES】实现MySql函数Median

本方法只支持在聚合函数窗口中调用 不支持在GROUP BY中使用&#xff0c;使用plsql写的玩意新能都会稍微差一些 建议使用原生方法修改 CREATE OR REPLACE FUNCTION _final_median(numeric[])RETURNS numeric AS $$SELECT AVG(val)FROM (SELECT valFROM unnest($1) valORDER BY …

vue中动态出来返回的时间秒数,在多少范围显示多少秒,多少范围显示分,小时等等

在Vue中&#xff0c;你可以使用计算属性&#xff08;computed property&#xff09;或过滤器&#xff08;filter&#xff09;来根据动态返回的时间秒数来显示不同的时间单位&#xff0c;比如秒、分、小时等等。 下面是一个使用计算属性的示例&#xff1a; <template>&l…

【Python小游戏】消消乐丨喜羊羊与灰太狼(完整代码)

文章目录 写在前面喜羊羊与灰太狼PyGame入门消消乐注意事项写在后面写在前面 本期内容:基于pygame实现喜羊羊与灰太狼版消消乐小游戏 实验环境 python3.11及以上pycharmpygame安装pygame的命令: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pygame喜羊羊与灰…

毛虫目标检测数据集VOC格式550张

毛虫&#xff0c;一种令人惊叹的生物&#xff0c;以其独特的外貌和习性&#xff0c;成为了自然界中的一道亮丽风景。 毛虫的外观非常特别&#xff0c;身体呈圆柱形&#xff0c;表面覆盖着许多细小的毛发&#xff0c;这使得它们在叶子上伪装得非常好。它们的头部有一对坚硬的颚…

select for update会锁表还是行锁还是其它

select for update含义 select查询语句是不会加锁的&#xff0c;但是 select for update除了有查询的作用外&#xff0c;还会加锁呢&#xff0c;而且它是悲观锁哦。至于加了是行锁还是表锁&#xff0c;这就要看是不是用了索引/主键啦。 没用索引/主键的话就是表锁&#xff0c…

SpringCloud-高级篇(十)

&#xff08;1&#xff09;单节点Redis问题 缓存大家都不陌生&#xff0c;在企业里面只要做缓存都会用到Redis&#xff0c;我们在使用的时候都是做的单节点部署&#xff0c;单节点部署是存在一些问题的&#xff0c;分布式缓存正是Redis的集群&#xff0c;正是为了解决单节点部署…

大数据毕业设计:租房推荐系统 python 租房大数据 爬虫+可视化大屏 计算机毕业设计(附源码+文档)✅

毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路&#xff0c;大家在毕设选题&#xff…

广播及代码实现

广播&#xff08;Broadcast&#xff09;是一种网络通信方式&#xff0c;它允许一台设备向网络中的所有其他设备发送消息。广播通常用于在网络上传递一些信息&#xff0c;让所有设备都能接收并处理。在广播中&#xff0c;通信的目标是整个网络而不是特定的单个设备。 向子网中…

【JAVA】Java 中 Set集合常用方法

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 常用方法 代码示例 结语 我的其他博客 前言 Java中的Set接口提供了一种不允许包含重复元素的集合。常用的实现类有HashS…

把苹果手机上的备忘录转为长图片,分享给别人方法教程

在这个信息爆炸的时代&#xff0c;手机备忘录几乎成了我随身携带的“记忆宝库”。每当我脑海中闪现出一个想法、灵感或是需要记住的重要事项&#xff0c;我都会第一时间打开苹果手机的备忘录&#xff0c;将它们一一记录下来。备忘录的简洁界面和高效操作总能让我在忙碌的生活中…

正负样本分配策略simOTA

simOTA是YOLOX中提出的 正负样本分配策略&#xff08;OTA, SimOTA&#xff0c;TAS&#xff09; OTA源于2021年cvpr的论文&#xff0c;使训练和验证的标签有着更好的对应关系。 yolov5没有用到&#xff0c;只有一种loss&#xff1a; from utils.loss import ComputeLoss comput…

线性代数-第五课,第六课,第七课,第八课

第五课 判断某向量是否可由某向量组线性表示 把向量组组成一个行列式&#xff0c;计算行列式的秩 把所有向量放在一起构成一个行列式&#xff0c;计算行列式的秩 如果两个行列式的秩相等&#xff0c;表示可以线性表示&#xff0c;写答案的格式如下 线性表示&#xff1a;bk…

大模型应用实践:AIGC探索之旅

随着OpenAI推出ChatGPT&#xff0c;AIGC迎来了前所未有的发展机遇。大模型技术已经不仅仅是技术趋势&#xff0c;而是深刻地塑造着我们交流、工作和思考的方式。 本文介绍了笔者理解的大模型和AIGC的密切联系&#xff0c;从历史沿革到实际应用案例&#xff0c;再到面临的技术挑…

二、串行FLASH文件系统FatFs移植

经过上一节的分析&#xff0c;我们对文件系统有一定的理解了&#xff0c;这一节给大家介绍怎么把FatFs文件系统的这些代码移植到STM32S上&#xff0c;然后STM32利用这一些代码或者函数&#xff0c;以文件的格式对FLASH进行读写数据。 实则对diskio.c提供一些函数接口。 首先将…

Kubernetes-网络

一. 前言 flannel两种容器跨主机通信的方案&#xff0c;其中UDP模式是IP in UDP&#xff0c;即三层报文封装在UDP数据包中通信&#xff1b;而vxlan模式则是MAC in UDP&#xff0c;即二层报文封装在UDP数据包中通信 flannel UDP模式和vxlan模式都对数据包做了封解包&#xff0c…

手把手教你在Ubuntu22上安装VideoRetalking

VideoReTalking是一种新系统&#xff0c;可以根据输入音频编辑真实世界的谈话头部视频的面孔&#xff0c;即使具有不同的情感&#xff0c;也能生成高质量和口型同步的输出视频。我们的系统将这个目标分解为三个连续的任务&#xff1a; &#xff08;1&#xff09;具有规范表情的…

SpringBoot实现登录拦截器

SpringBoot实现登录拦截器 对于管理系统或其他需要用户登录的系统&#xff0c;登录验证都是必不可少的环节&#xff0c;在SpringBoot开发的项目中&#xff0c;通过实现拦截器来实现用户登录拦截并验证。 1、SpringBoot实现登录拦截的原理 SpringBoot通过实现HandlerIntercep…

普中STM32-PZ6806L开发板(HAL库函数实现-访问多个温度传感器DS18B20)

简介 我们知道多个DS18B20的DQ线是可以被挂在一起的, 也就是一根线上可以访问不同的DS18B20而不会造成数据错乱, 怎么做到的&#xff0c;其实数据手册都有说到&#xff0c; 就是靠64-bit ROM code 进行识别, 也可以理解成Serial Number进行识别, 因为主要差异还是在Serial Numb…