feat: 添加P3609题解,实现动态规划与记忆化搜索

添加了P3609题的解决方案,使用动态规划和记忆化搜索来计算在最多k次手势变化情况下的最大胜利次数。包含输入处理和结果输出逻辑。
This commit is contained in:
Zengtudor 2025-09-12 17:55:05 +08:00
parent 8aba3d8e3d
commit fb1f59a3f1

95
src/9/12/P3609.cpp Normal file
View File

@ -0,0 +1,95 @@
/*
--- dp
dp[i][j][k] =
1<=i<=1e5 i轮游戏
1<=j<=3
1<=k<=20
dp[i][1][k] = max(dp[i-1][1][k], dp[i][2][k-1], dp[i][3][k-1]) + iswin
dp[i][1][0] = dp[i-1][1][0] +iswin
---
def dfs(i,j,k):
if vis[i][j][k]:
return vis[i][j][k]
if i==0:
return 0
if k==0:
dfs(i-1,j,0) + iswin
for j in :
vis[i][j][k] = max(
imp! vis[i][j][k],
dfs(i-1,,k), dfs(i-1,j,k-1)
)+iswin
return vis[i][j][k]
ans = max(
dfs(n,1,k)
dfs(n,2,k)
dfs(n,3,k)
)
*/
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <istream>
#include <vector>
using ll = int64_t;
ll n,k;
std::vector<std::vector<std::vector<ll>>> vis;
std::vector<ll> v;
static inline bool iswin(const ll a,const ll b){
const ll tmp = a-b;
return tmp==-1 || tmp==2;
}
static inline ll dfs(ll i,ll j,ll k){
if(vis[i][j][k])return vis[i][j][k];
if(i==0)return 0;
if(k==0){
return vis[i][j][k] = dfs(i-1,j,0)+iswin(j, v[i]);
}
vis[i][j][k] = dfs(i-1,j,k)+iswin(j, v[i]);
for(ll nj=1;nj<=3;nj++){
if(nj==j)continue;
vis[i][j][k]=std::max(
vis[i][j][k],
dfs(i-1,nj,k-1)+iswin(j, v[i])
);
}
return vis[i][j][k];
}
int main(){
std::iostream::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin>>n>>k;
vis.resize(n+1,std::vector<std::vector<ll>>(3+1,std::vector<ll>(k+1)));
v.resize(n+1);
for(ll i=1;i<=n;i++){
char tmp;
std::cin>>tmp;
if(tmp=='H'){
v[i]=1;
}else if(tmp=='S'){
v[i]=2;
}else{
v[i]=3;
}
}
ll ans=0;
for(ll j=1;j<=3;j++){
for(ll nk=0;nk<=k;nk++){
ans=std::max(
ans,
dfs(n,j,nk)
);
}
}
std::cout<<ans<<"\n";
}