[ICPC 2024 Chengdu R] Athlete Welcome Ceremony题解

P15073 [ICPC 2024 Chengdu R] Athlete Welcome Ceremony

题目描述

成都即将举办 2025 年世界运动会。在开幕式运动员欢迎仪式上,将有 nnn 名志愿者穿着三种不同类型的传统民俗服装,列队欢迎运动员。这些服装类型用 a\texttt{a}ab\texttt{b}bc\texttt{c}c 表示。志愿者的位置已经确定,现在我们需要为他们分配服装。为了实现特定的视觉效果,相邻的志愿者不能穿着相同类型的服装。

在这 nnn 名志愿者中,一些人已经拥有三种民俗服装中的一种,而另一些人则没有任何服装,需要主办方提供定制服装。共有 QQQ 个定制计划,每个计划指定:制作 xxxa\texttt{a}a 型服装、yyyb\texttt{b}b 型服装和 zzzc\texttt{c}c 型服装。

对于每个定制计划,确定在将定制服装分发给没有服装的志愿者后,可以形成多少种不同的有效服装安排。具体来说,在不超过给定计划限制的条件下,计算分配 a\texttt{a}ab\texttt{b}bc\texttt{c}c 型服装的方案数。如果两种安排中同一名志愿者分配的服装类型不同,则视为不同的安排。注意,同一类型的服装彼此不作区分。由于数量可能非常大,请输出答案对 109+710^9+7109+7 取模的结果。

输入格式

  • 第一行包含两个整数 nnn1≤n≤3001\le n\le 3001n300)和 QQQ1≤Q≤1051\le Q\le 10^51Q105),分别表示志愿者人数和定制计划的数量。
  • 第二行是一个长度为 nnn 的字符串 sss。保证字符串 sss 仅包含字符 a\texttt{a}ab\texttt{b}bc\texttt{c}c?\texttt{?}?。如果第 iii 个字符是 a\texttt{a}ab\texttt{b}bc\texttt{c}c 之一,则表示第 iii 名志愿者已经拥有对应的服装;否则,如果是 ?\texttt{?}?,则表示第 iii 名志愿者没有任何服装。
  • 接下来的 QQQ 行,每行包含三个整数 x,y,zx, y, zx,y,z0≤x,y,z≤3000 \le x, y, z \le 3000x,y,z300),表示一个定制计划。保证 x+y+zx+y+zx+y+z 不小于没有服装的志愿者人数。

输出格式

输出 QQQ 行,第 iii 行包含一个整数,表示满足第 iii 个定制计划要求的有效服装安排数量。请输出答案对 109+710^9+7109+7 取模的结果。

输入输出样例 #1

输入 #1

6 3
a?b??c
2 2 2
1 1 1
1 0 2

输出 #1

3
1
1

输入输出样例 #2

输入 #2

6 3
??????
2 2 2
2 3 3
3 3 3

输出 #2

30
72
96

说明/提示

在第一个样例中,第一个定制计划的有效服装安排是 acbabc\texttt{acbabc}acbabcacbcac\texttt{acbcac}acbcacacbcbc\texttt{acbcbc}acbcbc

翻译由 DeepSeek V3 完成

思路

考虑DP,fi,j,k,lf_{i,j,k,l}fi,j,k,l表示到i,a选j个,b选k个,当前点为l。
转移则容易。
然后做个后缀和,讨论范围即可。

代码见下

#include<bits/stdc++.h> 
using namespace std;
long long n,q,a[305],f[305][305][305][4],g[305][305],m=0,x,y,z,op=0;
char ch;
const long long mod=1e9+7;
int main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>ch;
		if(ch=='a'){
			a[i]=1;
		}
		else if(ch=='b'){
			a[i]=2;
		}
		else if(ch=='c'){
			a[i]=3;
		}
		else{
			a[i]=0;
			m++;
		}
	}
	f[0][0][0][0]=1;
	for(int i=1;i<=n;i++){
		if(a[i]!=0){
			for(int j=0;j<=m;j++){
				for(int k=0;k<=m;k++){
					for(int l=0;l<=3;l++){
						if(a[i]!=l){
							f[i][j][k][a[i]]=(f[i][j][k][a[i]]+f[i-1][j][k][l])%mod;
						}
					}
				}
			}
		}
		else{
			for(int j=0;j<=m;j++){
				for(int k=0;k<=m;k++){
					if(j>=1){
						f[i][j][k][1]=(f[i][j][k][1]+f[i-1][j-1][k][0])%mod;
						f[i][j][k][1]=(f[i][j][k][1]+f[i-1][j-1][k][2])%mod;
						f[i][j][k][1]=(f[i][j][k][1]+f[i-1][j-1][k][3])%mod;
					}
					if(k>=1){
						f[i][j][k][2]=(f[i][j][k][2]+f[i-1][j][k-1][0])%mod;
						f[i][j][k][2]=(f[i][j][k][2]+f[i-1][j][k-1][1])%mod;
						f[i][j][k][2]=(f[i][j][k][2]+f[i-1][j][k-1][3])%mod;                        
					}
					f[i][j][k][3]=(f[i][j][k][3]+f[i-1][j][k][0])%mod;
					f[i][j][k][3]=(f[i][j][k][3]+f[i-1][j][k][1])%mod;
					f[i][j][k][3]=(f[i][j][k][3]+f[i-1][j][k][2])%mod;                          
				}
			}
		}
		// for(int j=0;j<=m;j++){
		//     for(int k=0;k<=m;k++){
		//         for(int l=0;l<=3;l++){
		//             cout<<i<<" "<<j<<" "<<k<<" "<<l<<" "<<f[i][j][k][l]<<endl;
		//         }
		//     }
		// }
	}
	for(int i=0;i<=m;i++){
		for(int j=0;j<=m;j++){
			for(int l=0;l<=3;l++){
				g[i][j]=(g[i][j]+f[n][i][j][l])%mod;
			}
			//cout<<i<<" "<<j<<" "<<g[i][j]<<endl;
			if(j!=0){
				g[i][j]=(g[i][j]+g[i][j-1])%mod;
			}
		}
	}
	while(q--){
		cin>>x>>y>>z;
		x=min(x,m);
		y=min(y,m);
		z=min(z,m);
		op=0;
		for(int i=0;i<=x;i++){
			if(m-i-z<=y){
				if(m-i-z-1>=0){
					op=(op+g[i][y]-g[i][m-i-z-1]+mod)%mod;
				}
				else{
					op=(op+g[i][y])%mod;
				}
			}
		}
		cout<<op<<"\n";
	}
	return 0; 	
}
posted @ 2026-01-26 21:08  bz02_2023f2  阅读(5)  评论(0)    收藏  举报  来源