当前位置: 首页 > news >正文

【补题】The 3rd Universal Cup. Stage 15: Chengdu B. Athlete Welcome Ceremony

题意:给定一个字符串,由a、b、c、?组成,?可以由自己填写a、b、c任意一个字符,接下来只要求字符串相邻字符之间不重复,然后给出q个询问,每个询问给出多余的a,b,c字符,问有多少种方式填写满足要求的字符串

思路:

首先,非常明显的纯血dp,dp就是了,问题是怎么dp,个人的dp写法感觉有点愚蠢。

如果你想自己尝试写的话,很明显:
1.这个dp是一个类似线性的,也就是询问填写的地方即可。
2.到那个位置的时候,以什么结尾影响很明显,因为题目也就这么一个限制条件。
3.填写的数量情况很重要,毕竟决定了答案,这道题三维dp是至少的。

到此,你就完成了一个dp,我们假设四维dp[a][b][c][p],也就是填写的a数量,b数量,c数量,以及结尾。
但是这个dp是回答a+b+c严格等于空位的答案,我们要的是大于等于的,因为给的a,b,c数量不是严格等于空位,用什么呢?

考虑前缀和,本题第二个难点,那么是三维前缀和。
为什么是前缀和?因为继续使用dp,很难避免重复的情况,而前缀和,其实就是把当前位置的信息传递给更高层,本身的性质是保证不会重的,如果思考不清楚可以从低维前缀和考虑。

那么本题完成,代码:

写的不太好,dp是[a][b][c][p],实际上c可以由a,b直接算,应该能改成滚动数组,少302个三维是不是。
dp递推的代码应该可以写的更优美,交给你们了,鄙人就是傻子版

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N=1e6+5;
const int MOD=1e9+7;
const int INF=1e18;int dp[305][305][305][3];
int ans[305][305][305];void solve(){int n,m;cin >> n >> m;string s;cin >> s;s=" "+s;s=s+" ";if(s[1]=='?') dp[1][0][0][0]=dp[0][1][0][1]=dp[0][0][1][2]=1;else if(s[1]=='a') dp[1][0][0][0]=1;else if(s[1]=='b') dp[0][1][0][1]=1;else if(s[1]=='c') dp[0][0][1][2]=1;int A=0,B=0,C=0;for(int i=0;i<s.size();i++){if(s[i]=='a') A++;else if(s[i]=='b') B++;else if(s[i]=='c') C++;}for(int i=2;i<=n;i++){for(int j=0;j<=i;j++){for(int k=0;k<=i-j;k++){int a=j,b=k,c=i-j-k;if(s[i]!='?'){if(a!=0 && s[i]=='a' && s[i+1]!='a' && s[i-1]!='a'){dp[a][b][c][0]+=dp[a-1][b][c][1];dp[a][b][c][0]+=dp[a-1][b][c][2];dp[a][b][c][0]%=MOD;dp[a][b][c][1]=dp[a][b][c][2]=0;}else if(b!=0 && s[i]=='b' && s[i+1]!='b' && s[i-1]!='b'){dp[a][b][c][1]+=dp[a][b-1][c][0];dp[a][b][c][1]+=dp[a][b-1][c][2];dp[a][b][c][1]%=MOD;dp[a][b][c][0]=dp[a][b][c][2]=0;}else if(c!=0 && s[i]=='c' && s[i+1]!='c' && s[i-1]!='c'){dp[a][b][c][2]+=dp[a][b][c-1][1];dp[a][b][c][2]+=dp[a][b][c-1][0];dp[a][b][c][2]%=MOD;dp[a][b][c][0]=dp[a][b][c][1]=0;}else{dp[a][b][c][0]=dp[a][b][c][1]=dp[a][b][c][2]=0;}}else{for(int l=0;l<3;l++){if(a!=0 && l==0 && s[i+1]!='a' && s[i-1]!='a'){dp[a][b][c][l]+=dp[a-1][b][c][1];dp[a][b][c][l]+=dp[a-1][b][c][2];}else if(b!=0 && l==1 && s[i+1]!='b' && s[i-1]!='b'){dp[a][b][c][l]+=dp[a][b-1][c][0];dp[a][b][c][l]+=dp[a][b-1][c][2];}else if(c!=0 && l==2 && s[i+1]!='c' && s[i-1]!='c'){dp[a][b][c][l]+=dp[a][b][c-1][0];dp[a][b][c][l]+=dp[a][b][c-1][1];}else{dp[a][b][c][l]=0;}dp[a][b][c][l]%=MOD;}}}}}int p=n-A-B-C;for(int i=0;i<=p;i++){for(int j=0;j<=p-i;j++){for(int l=0;l<3;l++){ans[i][j][p-i-j]+=dp[i+A][j+B][p-i-j+C][l],ans[i][j][p-i-j]%=MOD;}}}for(int i=1;i<=300;i++){for(int j=0;j<=300;j++){for(int k=0;k<=300;k++){ans[i][j][k]+=ans[i-1][j][k],ans[i][j][k]%=MOD;}}}for(int i=0;i<=300;i++){for(int j=1;j<=300;j++){for(int k=0;k<=300;k++){ans[i][j][k]+=ans[i][j-1][k],ans[i][j][k]%=MOD;}}}for(int i=0;i<=300;i++){for(int j=0;j<=300;j++){for(int k=1;k<=300;k++){ans[i][j][k]+=ans[i][j][k-1],ans[i][j][k]%=MOD;}}}for(int i=0;i<m;i++){int xa,xb,xc;cin >> xa >> xb >> xc;cout << ans[xa][xb][xc]%MOD << '\n';}}signed main(){IOS;int t=1;// cin >> t;while(t--){solve();}
}

http://www.dtcms.com/a/533319.html

相关文章:

  • SZU大学物理1实验报告|薄透镜
  • 深入理解sigaction函数:Linux信号处理机制与使用指南
  • 网站设计公司哪家专业在线种子资源网
  • 便宜做网站如何免费做网站赚钱
  • 4 Initialization and Training(初始化和训练)
  • 简易银行系统->多线程高并发
  • 【系统分析师】高分论文:论基于构件的软件开发(气象灾害影响评估系统)
  • 【java面向对象进阶】------多态综合案例
  • 做一个内容网站多少钱wordpress调用导航
  • 惠州网站开发公司电话个人兴趣图片集网站建设
  • C++ list 类的使用
  • 怎么利用QQ空间给网站做排名没有专项备案的网站
  • 显示官网字样的网站怎么做wordpress 多站点主题
  • 如何建设一个新的网站快手推广软件免费版
  • 国内十大搜索引擎网站安徽网络关键词优化
  • 【Linux】定制Linux系统
  • 个人网站备案取消网站建设管理分工
  • 企业网站建设的趋势手机网站建设的整体流程图
  • 松原做招聘的网站有哪些系统优化的意义
  • 业务流程图 —— 讲清“谁做了什么事”
  • 天津网站建设咨询杭州景观设计公司排行
  • 10.5 小项目:如何用 JavaScript 实现一个高效的时间+Token过期容器?
  • 网站备案帐号找回密码免费友链平台
  • Every other Cycle Command Input(隔循环命令输入)
  • 更换docker默认镜像仓库地址方法
  • 福建省交通建设质量安全监督局网站软文写作技巧
  • 装饰公司营销型网站设计网站图片等比缩小
  • 高端网站制作价格大型大型网站建设方案ppt模板
  • 【底层机制】Linux内核4.10版本的完整存储栈架构讲解--用户空间到物理设备完整IO路径
  • nodejs 使用speaker + ffmpeg 实现静默播放MP3