首页 > 其他分享 >Atcoder Grand Contest 046 D - Secret Passage

Atcoder Grand Contest 046 D - Secret Passage

时间:2023-05-08 09:00:47浏览次数:34  
标签:Atcoder ok Contest int 305 Passage && 三元组 DP

思路挺自然的一道 agc。

首先发现删除完字符后的状态可以用一个三元组 \((i,j,k)\) 表示,其中 \(i\) 表示删除完之后只剩 \([i+1,n]\) 的后缀,\(j\) 表示可以在后面插入 \(j\) 个 \(0\),\(k\) 表示可以在后面插入 \(k\) 个 \(1\),显然不同的三元组能够得到的串是不同的,而一组三元组可以得到的串的个数可以 DP 求解,具体来说,倒着 DP,同时为了防止算重,我们强制要求 \(1\) 的后面只能添加 \(0\),\(0\) 的后面只能添加 \(1\),这样转移是 \(O(1)\) 的,具体实现见代码。

接下来考虑哪些三元组 \((i,j,k)\) 可以得到。考虑正着 DP,那么发现每次有两种选择:

  • 从 \(s_{i+1},s_{i+2}\) 中保留一个,删除一个
  • 从保留的字符中拿出一个 \(s_{i+1}\oplus 1\),插在开头,然后删除这个 \(s_{i+1}\oplus 1\) 同时保留 \(s_{i+1}\)。

转移同样可以 \(O(1)\),总复杂度 \(O(n^3)\)。

#include<bits/stdc++.h>
using namespace std;
const int MOD=998244353;
void add(int &x,int v){((x+=v)>=MOD)&&(x-=MOD);}
int n,ok[305][305][305],dp[305][305][305],res;
char s[305];
int main(){
	scanf("%s",s+1);n=strlen(s+1);ok[0][0][0]=1;
	for(int i=1;i<=n;i++)for(int j=n;~j;j--)for(int k=n;~k;k--){
		ok[i][j][k]|=ok[i-1][j][k];
		ok[i][j][k]|=ok[i][j+1][k];
		ok[i][j][k]|=ok[i][j][k+1];
		if(j&&i>=2&&(s[i]=='0'||s[i-1]=='0'))ok[i][j][k]|=ok[i-2][j-1][k];
		if(k&&i>=2&&(s[i]=='1'||s[i-1]=='1'))ok[i][j][k]|=ok[i-2][j][k-1];
		if(j&&s[i]=='0')ok[i][j][k]|=ok[i-1][j-1][k+1];
		if(k&&s[i]=='1')ok[i][j][k]|=ok[i-1][j+1][k-1];
	}
	dp[n][0][0]=1;
	for(int i=n;i;i--)for(int j=0;j<=n;j++)for(int k=0;k<=n;k++){
		add(dp[i-1][j][k],dp[i][j][k]);
		if(s[i]=='0')add(dp[i][j][k+1],dp[i][j][k]);
		if(s[i]=='1')add(dp[i][j+1][k],dp[i][j][k]);
	}
	for(int i=0;i<=n;i++)for(int j=0;j<=n;j++)for(int k=0;k<=n;k++)
		if(ok[i][j][k])add(res,dp[i][j][k]);
	add(res,MOD-1);printf("%d\n",res);
	return 0;
}

标签:Atcoder,ok,Contest,int,305,Passage,&&,三元组,DP
From: https://www.cnblogs.com/tzcwk/p/agc046D.html

相关文章

  • 2023ccpc湖北省赛/2023 Hubei Provincial Collegiate Programming Contest个人题解
    2023HubeiProvincialCollegiateProgrammingContestAPrimeMagicWalkAlonehasasequence\(a_1,a_2,...,a_n\),andhecanuseamagiconit:Chooseanoddprimenumber\(p\)andaninterval\([l,r]⊆[1,n]\)satisfying\(r−l+1=p\),andthenadd......
  • AtCoder Regular Contest 159简要题解
    AtCoderRegularContest159传送门A-CopyandPasteGraph图的邻接矩阵为\[\left(\begin{matrix}A&A&\cdots&A\\A&A&\cdots&A\\\cdots&\cdots&\cdots&\cdots\\A&A&\cdots&A\e......
  • AtCoder Regular Contest 134 E Modulo Nim
    洛谷传送门AtCoder传送门It'sallMAGIC这种题目一般先考虑局面要满足什么条件能必胜,然后根据这个性质来计数。如果把黑板上的数写成一个集合\(S\),那么:\(\varnothing\)为必胜态,\(\{1\},\{2\}\)显然为必败态,打表发现其他单元素集合都为必胜态;如果\(\existsx\inS,x......
  • AtCoder Beginner Contest 242
    A-T-shirt#include<bits/stdc++.h>usingnamespacestd;int32_tmain(){doublea,b,c,x; cin>>a>>b>>c>>x; if(x<=a)cout<<"1.000000000000"; elseif(x>b)cout<<&qu......
  • AtCoder Beginner Contest 285(B,D,E,F)
    AtCoderBeginnerContest285(B,D,E,F)B(暴力,非二分)B这道题其实很简单,但是我在\(vp\)的过程,有了一个错误的认识,纠正一下那就是,我把这个当成了一个二分题,并且还有点坚定不移,后来细想,发现不对二分,适用于那种边界分明的那种题(左边一定是符合条件,右边一定符合条件,也可表达为线性......
  • [AtCoder-AT_ABC108_B]题解(C++)
    PartIPreface原题目(Luogu)原题目(AtCoder)PartIISketchPartIIIAnalysis观察这道题,我们很容易想到,必须推导出\(x1,y1,x2,y2\)与\(x3,y3,x4,y4\)之间的关系。我们观察下图。可以发现:\(\begin{aligned}\begin{cases}x3=x2-(y2-y1)\\y3=y2+(x2-......
  • AtCoder Regular Contest 131 E Christmas Wreath
    洛谷传送门AtCoder传送门不难猜想有解充要条件为\(n\ge5\)且\(\frac{n(n-1)}{2}\bmod3=0\)。发现如果钦定一个点的出边都为同一种颜色,那么条件\(2\)一定满足。那么题目等价于把\(\{0,1,...,n-1\}\)分成\(3\)组使得每组的和相等。这个东西可以随便dp做,也不......
  • AtCoder Regular Contest 131 D AtArcher
    洛谷传送门AtCoder传送门观察可以发现:使每支箭的距离都为\(D\)一定不劣;每支箭坐标一定为整数;设最左边的箭坐标为\(x\),那么\(x\)太小时可以把最左边的箭移到最右边,\(x\)太大时可以把最右边的箭移到最左边。计算可得\(x\)的最优取值范围为\(x\in[-\left\lfloor\fr......
  • Asia Dhaka Regional Contest C (阶乘分解)
    原题点这前置知识点:阶乘分解可看这篇博客题意:给出\(n\),问\(n!\)的因子的因子的个数和。思路:学会上面的阶乘分解之后,我们能一眼看出来这道题也一定跟它有关系,所以我们按照惯例先对\(n!\)进行质因数分解。n!=\({p_1}^{a_1}\times\)\({p_2}^{a_2}\)\(\times\)\({p......
  • SMU Spring 2023 Trial Contest Round 10
    A.RemoveDuplicates#include<bits/stdc++.h>//#defineinf0x3f3f3f3f#defineendl'\n'#defineintlonglongusingnamespacestd;constintN=2e3+10,mod=1e9+7;//typedeflonglongll;typedefpair<int,int>PII;//queue......