关键词:递推关系,动态规划
试题链接:
https://www.nowcoder.com/questionTerminal/5e7d025e91ab468f909cb93d431b89c3
问题描述:
根据算法笔记上的思路:
对于每一个A,其左侧所有P的数目与其右侧所有T的数目相乘得到的结果即为这个A能够组成的pat数,统计所有A能够组成的pat数求和,即为题目的答案。
备注:
最好每次相加的时候都能够取一次模,不然可能有溢出的风险。
解决方案:
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=100010;
const int mod=1000000007;
//算法笔记思路:寻找每一个A左边的P的个数和右边的T的个数
int main(){
char str[maxn];
int leftP[maxn]={0};
int ans=0,rightT=0;
//获取输入字符串
cin>>str;
int len=strlen(str);
for(int i=0;i<len;i++){ //遍历字符串
if(i!=0){
leftP[i]=leftP[i-1];//继承上一位的结果
}
if(str[i]=='P'){
leftP[i]++; //P的计数+1
}
}
for(int i=len-1;i>=0;i--){ //从右向左遍历字符串
//当前字符为T则计数+1
if(str[i]=='T'){
rightT++;
//当前字符为A则左边P数与右边T数相乘得到当前A可组成pat的结果
}else if(str[i]=='A'){
ans=(ans+leftP[i]*rightT)%mod;//每次都要取余,否则可能溢出
}
}
cout<<ans;
return 0;
}
代码简化:
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=100010;
const int mod=1000000007;
//参考大佬简练的代码
int main(){
char str[maxn];
int p=0,pa=0,pat=0;
//获取输入字符串
cin>>str;
int len=strlen(str);
for(int i=0;i<len;i++){ //遍历字符串
if(str[i]=='P'){
p++;
}else if(str[i]=='A'){
pa+=p; //当前A和之前所有P可以组成PA的数目
}else if(str[i]=='T'){
pat+=pa;//当前T和之前所有PA可以组成PAT的数目
pat=pat% mod;
}
}
cout<<pat;
return 0;
}