首页 > 其他分享 >AT_abc344_d 题解

AT_abc344_d 题解

时间:2024-03-09 23:00:45浏览次数:36  
标签:题解 rep abc344 字符串 size LL dp define

赌狗天天输的一集。

大意

你最开始有一个空字符串 \(S\)。

你还有编号为 \(1, 2, \dots, N\) 的袋子,每个袋子都包含一些字符串。

袋子 \(i\) 包含 \(A_i\) 个字符串 \(S_{i,1}, S_{i,2}, \dots, S_{i,A_i}\)。

对 \(i = 1, 2, \dots, N\) 重复以下步骤仅一次(这里原题没有讲清楚):

  • 执行以下两个操作之一:
    • 支付 \(1\) 日元,从袋子 \(i\) 中选择一个字符串,并将其接到 \(S\) 的末尾。
    • 睡觉(啥都不干)。

给定一个字符串 \(T\),求使最后 \(S\) 等于 \(T\) 所需的最小金额。
如果无法使最后的 \(S\) 等于 \(T\),则打印 -1

思路

我最开始打了个爆搜,众所周知寄了。

然后疯狂推 DP,一阵木大木大后我开窍了:

用 \(dp_{i,j}\) 表示处理到了第 \(i\) 个袋子,现在这个字符串已经有 \(j\) 位(而且与 \(t\) 匹配)了。

初始化所有位置为无穷大(比如说我取的一千多,够了)。

首先枚举每个袋子。

然后肯定是要 dp[i][j]=dp[i-1][j] 的(万一你这组没出息你要保留实力)

然后你枚举一下袋子里的哪个字符串,再枚举一下 \(k\)(加上这个字符串之前的长度)。

如果加上这个字符串后能与 \(t\) 匹配,dp[i][k+s[i][j].size()-1]=min(dp[i][k+s[i][j].size()-1],dp[i-1][k-1]+1);。注意我的代码是从 \(1\) 开始的。

最后看一下 dp[n][t.size()],如果不是无穷大,就输出它,否则就输出 -1

代码

#include<stdio.h>
#include<bits/stdc++.h>
#define N 1000010
#define MOD 998244353
#define esp 1e-8
#define INF 999999999999999999
#define LL long long
#define rep(i,a,b,g) for(LL i=a;i<=b;i+=g)
#define rem(i,a,b,g) for(LL i=a;i>=b;i-=g)
#define repn(i,a,b,g) for(LL i=a;i<b;i+=g)
#define remn(i,a,b,g) for(LL i=a;i>b;i-=g)
#define pll pair<LL,LL>
#define mkp(x,y) make_pair(x,y)
#define i128 LL
#define lowbit(x) ((x)&(-(x)))
#define lc (u<<1)
#define rc (u<<1|1)
using namespace std;
void read(i128 &x)
{
	i128 f=1;
	x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
}
void write(i128 x)
{
	if(x>=10)write(x/10);
	putchar(x%10+'0');
}
LL n,a[110],dp[110][110];
string t,s[110][20];
int main()
{
	cin>>t>>n;
	rep(i,0,n,1)rep(j,1,t.size(),1)dp[i][j]=1029;
	rep(i,1,n,1)
	{
		cin>>a[i];
		rep(j,1,a[i],1)cin>>s[i][j];
	}
	rep(i,1,n,1)
	{
		rep(j,0,t.size(),1)dp[i][j]=dp[i-1][j];
		rep(j,1,a[i],1)
		{
			for(LL k=1;k+s[i][j].size()-1<=t.size();k++)
			{
				bool f=1;
				rep(l,1,s[i][j].size(),1)
				{
					if(s[i][j][l-1]!=t[k+l-2])
					{
						f=0;
						break;
					}
				}
				if(f)
				{
					dp[i][k+s[i][j].size()-1]=min(dp[i][k+s[i][j].size()-1],dp[i-1][k-1]+1);
				}
			}
		}
	}
	if(dp[n][t.size()]==1029)cout<<-1<<endl;
	else cout<<dp[n][t.size()]<<endl;
	return 0;
}

标签:题解,rep,abc344,字符串,size,LL,dp,define
From: https://www.cnblogs.com/cppom/p/-/ABC344D-tijie

相关文章

  • P10238 [yLCPC2024] F. PANDORA PARADOXXX 题解
    分析考虑时光倒流。对于需要合并的两个连通块\(x,y\),其合并之后的最远点对距离一定是合并之前的两组点对中产生的。在合并的时候枚举点对,取距离最大值即可。由于我们是倒着来的,所有连通块的最远点对距离最大值不减,所以能直接在合并之后取最大值。维护连通块用并查集即可。复杂......
  • P10237 [yLCPC2024] E. Latent Kindom 题解
    分析一眼了非最优解。考虑二分答案。对于二分出来的中位数\(x\),到\(a_i\)和\(a_j\)里边又去二分。得到两个序列中不超过\(x\)的数的数量。若这个数量\(cnt\ge\lceil\frac{len_{i}+len_{j}}{2}\rceil\),则\(x\)可能成为中位数,然后继续二分即可。把序列离散化,复杂度......
  • [ABC219F] Cleaning Robot 题解
    [ABC219F]CleaningRobot题解思路解析要点:将整个图拆分成每一轮的每一个点单独考虑贡献。首先看到\(k\le10^{12}\)发现不能直接枚举\(k\)轮,于是开始找每一轮的规律。首先可以知道,如果操作固定,那么起点和路径上每一个点以及终点的相对位置不会改变。也就是说每一轮的起......
  • CF1583E Moment of Bloom 题解
    题意:给定一张\(n\)个点\(m\)条边无向连通图,以及\(q\)个点对\((a,b)\),出事每条边权值为\(0\)。对于每个点对我们需要找一条从一个点到另一个点的简单路径,将所有边的权值加一。要求构造一种方案使得每条边权值都是偶数。如果不行,输出最少还要几个点对才能满足要求。\(n,m......
  • CF1634E Fair Share 题解
    题意:给定\(m\)个长度为偶数的数组,\(L,R\)是初始为空的两个多重集。将每个数组恰好一半的数放入\(L\),另一半放入\(R\),要求最后\(L=R\),要求构造方案或判断无解。\(m\le10^5,\sumn\le10^5\)。思路:首先我们不难想到,对于同一个数组内相同的值,可以成双除去,所以我们可以......
  • Interval GCD 题解
    题目描述给定一个长度为\(\largen\)的数组\(\largea\),以及\(\largem\)条指令(\(n\leq5\times10^5,m\leq10^5\)),每条指令可能是以下两种之一:“\(\large\operatorname{C\l\r\d}\)”,表示把\(\largea[l],a[l+1],…,a[r]\)都加上\(\larged\)。“\(\large\operatorn......
  • CF1264D2 Beautiful Bracket Sequence (hard version) 题解
    括号深度的本质,其实就是删除若干个字符以后使得左边一半全是(,右边一半全是),最终(的个数的最大值。那么就一定存在一个位置使得在这个位置以及之前的字符中(的个数等于这个字符后)的个数。考虑枚举这个位置,记它左边的(的个数为\(a\)、?的个数为\(x\),右边的)的个数......
  • [CF696B] Puzzles 题解
    首先很好想到要用树形\(dp\)。然后设\(dp_i\)为遍历到第\(i\)个点的期望时间,\(sz_i\)代表\(i\)的子树大小。发现有转移方程:\[dp_i=dp_{fa_i}+1+\sum\limits_{j\infa_i且j\nei}sz_j\timesq\]其中\(q\)为一个常数,代表在排列中\(j\)在\(i\)前的概率。很容易发......
  • 无聊的数列[题解]
    无聊的数列[link1][link2]题目大意给定一个数列\(A\)有两种操作:将数列中\(A_i\)(\(L\leqi\leqR\))加上一个等差数列(首项D公差K)查询数列中第P位数区间加上一个等差数列可以用差分来解决例原序列:000000差分序列:000000等差序列:13579(首项1......
  • 课堂练习 最大值 原题链接+题解
    题目可以去我的洛谷题库看:https://www.luogu.com.cn/problem/U412348(带数据,真难出)题解考虑两种解题方式。由于题目范围较小,可以check+暴力,如果范围大一点,可以check+二分答案。先讲check函数,小学四年级数学书说了,这种问题也被它叫做“铺地砖”问题,计算剪出的正方形数量的方......