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

news2025/2/22 18:53:11

目录

 今日知识点:

金字塔的正反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.coloradmin.cn/o/1356536.html

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

相关文章

2下载Spring,第一个Spring程序+引用Log4j2

https://www.yuque.com/dujubin/ltckqu/kipzgd#&#xff0c;注意的是&#xff0c;现在&#xff08;202401&#xff09;SpringFramework从release搬到了snapshot下&#xff0c;在这下面找到6.0.2下载. 下载后解压到文件夹&#xff0c;整个框架包含非常多jar包。 然后就可以在p…

机器人动力学一些笔记

动力学方程中&#xff0c;Q和q的关系(Q是sita) Q其实是一个向量&#xff0c;q(Q1&#xff0c;Q2&#xff0c;Q3&#xff0c;Q4&#xff0c;Q5&#xff0c;Q6)&#xff08;假如6个关节&#xff09; https://zhuanlan.zhihu.com/p/25789930 举个浅显易懂的例子&#xff0c;你在房…

详细解读QLC SSD无效编程问题-1

此前小编关于QLC SSD有过多篇文章&#xff0c;具体参考如下&#xff1a; 为什么QLC NAND才是ZNS SSD最大的赢家&#xff1f; HDD与QLC SSD深度对比&#xff1a;功耗与存储密度的终极较量 QLC SSD在数据中心的发展前景如何&#xff1f; 多维度深入剖析QLC SSD硬件延迟的来源 …

CNN——VGG

1.VGG简介 论文下载地址&#xff1a;https://arxiv.org/pdf/1409.1556.pdf VGGNet 是由牛津大学视觉几何小组&#xff08;Visual Geometry Group, VGG&#xff09;提出的一种深层卷积网络结构&#xff0c;他们以 7.32% 的错误率赢得了 2014 年 ILSVRC 分类任务的亚军&#xff…

MindSpore Serving与TGI框架 の 对比

一、MindSpore Serving MindSpore Serving是一款轻量级、高性能的服务工具&#xff0c;帮助用户在生产环境中高效部署在线推理服务。 使用MindSpore完成模型训练>导出MindSpore模型&#xff0c;即可使用MindSpore Serving创建该模型的推理服务。 MindSpore Serving包含以…

C# 2中的一些小特性

一、局部类型 在C#当中有这样一个关键字partial 用来声明类&#xff0c;结构&#xff0c;接口分为多个部分来声明。使用场景可以一部分类中写实例方法&#xff0c;一部分写属性&#xff0c;我在实际工作测试中就是将属性与实际方法是分开的。相互之间的成员互相通用。 举个例子…

【普中开发板】基于51单片机的篮球计分器液晶LCD1602显示( proteus仿真+程序+设计报告+讲解视频)

基于普中开发板51单片机的篮球计分器液晶LCD1602显示 1.主要功能&#xff1a;讲解视频&#xff1a;2.仿真3. 程序代码4. 设计报告5. 设计资料内容清单&&下载链接资料下载链接&#xff08;可点击&#xff09;&#xff1a; 基于51单片机的篮球计分器液晶LCD1602显示 ( pr…

【水浸传感器】软硬件一体水浸监测整套方案远程监测解决各种环境漏水问题

一、痛点分析 在工业生产中&#xff0c;水浸传感器可以安装在数据中心、半导体厂房、输油管道、车间仓库、变电室等易发生水浸的区域。一旦检测到漏水情况&#xff0c;立即发出信号反馈。然而&#xff0c;水浸传感器分散在各个地点&#xff0c;导致管理不集中、不便捷&#xf…

关于TypeScript Interface你需要知道的10件事

TypeScript接口的10种使用场景——可能只有20%的web开发人员完全掌握它们 TypeScript中的接口是一个非常灵活的概念。除了抽象类的部分行为外&#xff0c;它还经常用于描述“对象的形状”。 必需的属性 在定义接口时&#xff0c;需要使用 interface 关键字: interface Use…

流量困境下,2024年餐饮商家的直播带货生意到底怎么做?

据官方数据显示&#xff0c;截至2023年2月&#xff0c;抖音生活服务餐饮商家直播间数量达到43万&#xff0c;2023年7月&#xff0c;抖音生活服务餐饮行业自播商家数较1月增长134%。可以说&#xff0c;直播带货已经成为餐饮商家的常态化的线上营销模式&#xff0c;也成为各大餐饮…

SwiftUI之深入解析ContentUnavailableView的实战应用

一、基本用法 SwiftUI 引入了新的 ContentUnavailableView 类型&#xff0c;允许在应用程序中展示空状态、错误状态或任何其他内容不可用的状态。那么&#xff0c;如何使用 ContentUnavailableView 引导用户浏览应用程序中的空状态呢&#xff1f;首先看看 ContentUnavailableV…

redis服务迁移数据工具--RDM

一、背景&#xff1a; 在日常的运维工作经常遇见各种数据迁移工作&#xff0c;例如mysql数据库迁移、redis数据库迁移、minio数据迁移等等工作。这里介绍一下redis数据库的迁移过程。 二、迁移思路&#xff1a; redis服务/集群的数据迁移思路是需要新建一个配置、密码一样的re…

NX/UG二次开发—C\C++开发单个DLL支持多版本NX一种方法

1、去除附加包含目录下的NX相关的lib文件&#xff1a; 2、从对应的dll导出ufun函数和NXopen函数&#xff1a; libufun.dll; libufun_cam.dll; libufun_cae.dll; libufun_die.dll; libufun_vdac.dll; libufun_weld.dll; libugopenint.dll; libugopenint_cae.dll; libugopenint_…

感知与认知的碰撞,大模型时代的智能文档处理范式

目录 0 写在前面1 GPT4-V&#xff1a;拓宽文档认知边界2 大语言模型的文档感知缺陷3 大一统文档图像处理范式3.1 像素级OCR任务3.2 OCR大一统模型3.3 长文档理解与应用 4 总结抽奖福利 0 写在前面 由中国图象图形学学会青年工作委员会发起的第十九届中国图象图形学学会青年科学…

Java重修第一天—学习数组

1. 认识数组 建议1.5倍速学习&#xff0c;并且关闭弹幕。 数组的定义&#xff1a;数组是一个容器&#xff0c;用来存储一批同种类型的数据。 下述图&#xff1a;是生成数字数组和字符串数组。 为什么有了变量还需要定义数组呢&#xff1f;为了解决在某些场景下&#xff0c;变…

chromium在中文用户名下无法编译的问题

新电脑没有太注意&#xff0c;起用户名的时候用了中文。 在编译chromium104的代码时&#xff0c;因为环境变量有中文导致编译失败&#xff1a; 因为我的电脑默认是使用gbk编码&#xff0c;而不是utf-8编码。 这个问题有三种解决办法&#xff1a; &#xff08;一&#xff09;把…

【Spark精讲】Spark on Hive性能优化

目录 第一章 1.1 集群配置概述 1.2 集群规划概述 第二章 Yarn配置 2.1 Yarn配置说明 yarn.nodemanager.resource.memory-mb yarn.nodemanager.resource.cpu-vcores yarn.scheduler.maximum-allocation-mb yarn.scheduler.minimum-allocation-mb 第三章 Spark的配置说…

在Ubuntu22.04上部署Stable Diffusion

在AI绘画软件领域Stable-Diffusion&#xff08;简称SD&#xff09;在开源领域绝对是不二之选&#xff0c;他的插件方式可以让此软件具有更多的功能&#xff0c;开发者社群为此提供了大量免费高质量的外接预训练模型&#xff08;fine-tune&#xff09;和插件&#xff0c;并持续维…

深耕汽车检测设备领域,引领行业技术革新

在汽车工业飞速发展的今天&#xff0c;汽车检测技术作为保障车辆安全、提升维修效率的重要手段&#xff0c;日益受到行业内外的高度关注。康士柏汽车检测线设备厂家&#xff0c;作为这一领域的佼佼者&#xff0c;凭借其深厚的技术积累和卓越的产品品质&#xff0c;正引领着行业…

傅里叶级数、傅里叶变换、小波变换、离散余弦变换的理解

目录 1. 傅里叶级数2.傅里叶变换 1. 傅里叶级数 功能&#xff1a;能把任意周期性函数展开成一系列正弦、余弦函数的和。 公式&#xff1a; f ( x ) a 0 2 ∑ n 1 ∞ ( a n cos ⁡ ( 2 π n x T ) b n sin ⁡ ( 2 π n x T ) ) 傅里叶系数 a n 2 T ∫ x 0 x 0 T f ( x )…