动态规划专项---状态机模型

 

70530b4346544ad4821252fa57119ccc.jpeg

 


 

文章目录

  • 大盗阿福
  • 股票买卖IV
  • 股票买卖V
  • 设计密码
  • 修复DNA

一、大盗阿福OJ链接

·        本题思路:状态表示当前第i家店铺选择偷或者不偷的最大利益。状态计算:f[i][0]=std::max(f[i-1][0],f[i-1][1]);//如果第i家店铺被偷,则第i-1家店铺不能被偷,f[i][1]=f[i-1][0]+w[i];//如果第i家店铺不被偷,则第i-1家店铺随便安排。

#include <bits/stdc++.h>

constexpr int N=1e5+10;

int n;
int w[N];
int f[N][2]//状态表示当前第i家店铺选择偷或者不偷的最大利益

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);std::cout.tie(nullptr);

	int T;
	std::cin>>T;
	while(T--){
		std::cin>>n;
		for(int i=1;i<=n;i++) std::cin>>w[i];

		for(int i=1;i<=n;i++){
			f[i][0]=std::max(f[i-1][0],f[i-1][1]);//如果第i家店铺被偷,则第i-1家店铺不能被偷
			f[i][1]=f[i-1][0]+w[i];//如果第i家店铺不被偷,则第i-1家店铺随便安排。
		}

		std::cout<<std::max(f[n][0],f[n][1])<<std::endl;
	}
	return 0;
}

二、股票买卖IVOJ链接

        本题思路:状态表示:考虑前i天的股票,第i天是否交易且完成交易数位j的最大利润。状态计算之前首先初始化空仓情况全为0状态,然后进行状态间的计算,如果第i天的状态是持仓时,则第i天产生的行为可能是买入或者是持仓行为,此时为f[i,j,1]=std::max(f[i-1,j,1],f[i-1,j-1,1]-w[i]),如果第i天的状态是空仓时,则第i天产生的行为可能是卖出行为或者是空仓行为,此时为f[i,j,0]=std::max(f[i-1,j,0],f[i-1,j,1]+w[i])。

#include <bits/stdc++.h>

constexpr int N=1e5+10,M=110;

int n,k;
int w[N];
int f[N][M][2];//考虑前i天的股票,第i天的是否交易且完成的交易数为j的最大利润

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);std::cout.tie(nullptr);

	std::cin>>n>>k;
	for(int i=1;i<=n;i++) std::cin>>w[i];

	std::memset(f,-0x3f,sizeof f);
	for(int i=0;i<=n;i++) f[i][0][0]=0;//初始化为空仓

	for(int i=1;i<=n;i++){
		for(int j=0;j<=k;j++){
			if(j) f[i][j][0]=std::max(f[i-1][j][0],f[i-1][j][1]+w[i]);
			f[i][j][1]=std::max(f[i-1][j][1],f[i-1][j-1][0]-w[i]);
		}
	}

	int res=0;
	for(int j=0;j<=k;j++) res=std::max(res,f[n][j][0]);
	std::cout<<res<<std::endl;
	return 0;
}

三、股票买卖VOJ链接

        本题思路:本题是上面一题的变种多出了一个状态,所以我们可以用j=0表示当前没有股票,且不处于冷冻期,j=1表示当前有股票,j=2表示当前没有股票且处于冷冻期。状态表示:考虑到前i天的股市当前第i天的状态为j时的最大利润。

#include <bits/stdc++.h>

constexpr int N=1e5+10;

int n;
int w[N];
int f[N][3];//考虑前i天的股市当前第i天的状态为j时的最大利润

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);std::cout.tie(nullptr);

	std::cin>>n;
	for(int i=1;i<=n;i++) std::cin>>w[i];

	memset(f,-0x3f,sizeof f);
	f[0][0]=0;

	/*
	j=0表示当前没有股票且不处于冷冻期
	j=1表示当前有股票
	j=2表示没有股票而且还处于冷冻期
	 */
	for(int i=1;i<=n;i++){
		f[i][0]=std::max(f[i-1][0],f[i-1][2]);
		f[i][1]=std::max(f[i-1][0]-w[i],f[i-1][1]);
		f[i][2]=f[i-1][1]+w[i];
	}

	std::cout<<std::max(f[n][0],f[n][2])<<std::endl;
	return 0;
}

四、设计密码

五、修复DNA

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

‘(尐儍苽-℡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值