解题思路:
动态规划,做动态规划题时有两大核心其一我们要用一些状态去表示所有的集合(不重不漏)其二我们表示的这些状态都要能正确的转化过来估计这两大核心大家都应该很熟悉,就是很难做到 别急经过题目的数量和时间的沉淀大家肯定会弄明白的。
f[i][j][k] 表示前i招且第i招使用的技能为j且连用了k次所获得的最大伤害,题目说了总共有3中技能且最多连用2次连招,所以公用6种状态(有点多)分别是f[i][0][1],f[i][0][2],f[i][1][1],f[i][1][2],f[i][2][1],f[i][2][2]; 如何把这六种状态表示出来呢分f[i][j][k]肯定f[i-][j0][k0]转化过来的,f[i][0][2]是从分f[i-1][0][1]转化过来的,f[i][0][1]是从f[i-1][j][k](j=1,2,k=1,2)转化过来的后面四种状态类似前两种状态,显然答案是max(f[n][j][k]),时间复杂度为6n,废话不多说看代码吧,不过写的很乱
代码
#include<iostream>
#define int long long
using namespace std;
const int N=2e5+5;
char s[N];
int f[N][3][3];
signed main()
{
int n,a,b,c,d;
cin>>n>>a>>b>>c>>d;
cin>>s+1;
//把三种技能转化成数字表示
for(int i=1;i<=n;i++)
{
if(s[i]=='A')
s[i]='0';
if(s[i]=='B')
s[i]='1';
if(s[i]=='G')
s[i]='2';
}
for(int i=1;i<=n;i++)
{
if(s[i]=='0')
{
//把六种状态全部正确转化出来
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
f[i][0][1]=max(f[i][0][1],f[i-1][j][k]+d);
f[i][0][2]=max(f[i][0][2],f[i-1][0][1]+d);
for(int j=0;j<=2;j++)
{
for(int k=1;k<=2;k++)
{
if(j==1)
continue;
f[i][1][1]=max(f[i][1][1],f[i-1][j][k]+a);
}
}
f[i][1][2]=max(f[i][1][2],f[i-1][1][1]+a);
for(int j=0;j<2;j++)
for(int k=1;k<=2;k++)
f[i][2][1]=max(f[i][2][1],f[i-1][j][k]);
f[i][2][2]=max(f[i][2][2],f[i-1][2][1]);
}
if(s[i]=='1')
{ //把六种状态全部正确转化出来
for(int j=0;j<=2;j++)
{
for(int k=1;k<=2;k++)
{
if(j==1)
continue;
f[i][1][1]=max(f[i][1][1],f[i-1][j][k]+d);
}
}
f[i][1][2]=max( f[i][1][2],f[i-1][1][1]+d);
for(int j=0;j<2;j++)
{
for(int k=1;k<=2;k++)
f[i][2][1]=max(f[i][2][1],f[i-1][j][k]+c);
}
f[i][2][2]=max(f[i][2][2],f[i-1][2][1]+c);
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
f[i][0][1]=max(f[i][0][1],f[i-1][j][k]);
f[i][0][2]=max(f[i][0][2],f[i-1][0][1]);
}
if(s[i]=='2')
{ //把六种状态全部正确转化出来
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
f[i][0][1]=max(f[i][0][1],f[i-1][j][k]+b);
f[i][0][2]=max(f[i][0][2],f[i-1][0][1]+b);
for(int j=0;j<=2;j++)
{
for(int k=1;k<=2;k++)
{
if(j==1)
continue;
f[i][1][1]=max(f[i][1][1],f[i-1][j][k]);
}
}
f[i][1][2]=max(f[i][1][2],f[i-1][1][1]);
for(int j=0;j<2;j++)
{
for(int k=1;k<=2;k++)
f[i][2][1]=max(f[i][2][1],f[i-1][j][k]);
}
f[i][2][2]=max(f[i][2][2],f[i-1][2][1]);
}
}
int ans=0;
for(int j=0;j<=2;j++)
for(int k=1;k<=2;k++)
ans=max(ans,f[n][j][k]);
cout<<ans<<endl;
return 0;
}