专栏文章
题解:AT_arc197_a 网格路径并
AT_arc197_a题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mipcpctc
- 此快照首次捕获于
- 2025/12/03 09:51 3 个月前
- 此快照最后确认于
- 2025/12/03 09:51 3 个月前
AT_arc197_a 网格路径并
题目大意
给定一个 的白色网格以及一个长度为 的字符串 (字符为
D、R 和 ?),其中- 若 ,第 步只能向下走;
- 若 ,第 步只能向右走;
- 若 ,第 步可以自由选择(向下或向右)。
每次你可以按照 允许的走法走一条从 到 的路径,并将路径上所有格子染成黑色。你可以多次操作,目标是使黑色格子总数尽可能多,求最大黑色格子的数量。
解题思路
一个合法路径必须走恰好 次“下”和 次“右”。
设字符串中固定的
D 数量为 ,固定的字符总数为 为 ? 的个数,则在每条合法路径中,还需要把 ? 中的个字符选为
D(其余选为 R)。定义
pre[i] 为字符串前 个字符中 ? 的个数,考虑前 步中选取 个 ? 变为 ?,则要求对于第 前缀,合法的 数量即为
其中
和
其中
和
此时,固定的
最终答案为所有前缀( 到 )上合法取值数的总和。
由于对每个前缀只作常数次运算,整体时间复杂度为
CPPD 数量加上从 ? 中选出的 个 D,确定了当前下走的总次数,从而唯一确定了路径在网格中的位置。最终答案为所有前缀( 到 )上合法取值数的总和。
由于对每个前缀只作常数次运算,整体时间复杂度为
#include<bits/stdc++.h>
using namespace std;
void FileIO(){
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
namespace sunburstfan{
#define int long long
const int mod=1e9+7;
const int N=1e5+5;
void solve(){
int n,m;
cin>>n>>m;
string s;
cin>>s;
int len=n+m-2,totf=0,totd=0;
for(int i=0;i<len;i++){
if(s[i]=='?')totf++;
else if(s[i]=='D')totd++;
}
int d_re=(n-1)-totd;
//cout<<d_re<<" "<<totd<<"\n";
int ans=0;
vector<int> pre(len+1,0);
for(int i=1;i<=len;i++){
pre[i]=pre[i-1]+(s[i-1]=='?'? 1:0);
}
for(int i=0;i<=len;i++){
int cur=pre[i];
int l=max(0ll,d_re-(totf-cur)),u=min(cur,d_re);
if(l<=u){
ans+=(u-l+1);
}
}
cout<<ans<<"\n";
}
}
using namespace sunburstfan;
signed main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
//FileIO();
int T;
cin>>T;
while(T--){
solve();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...