文章目录
- 大盗阿福
- 股票买卖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