Codeforces Round #604 Div2

1265D Beautiful Sequence(构造 贪心)

题意:

​ 给你若干数量的0、1、2、3,用完所有的数字构造一个序列使得任意相邻两数相差恰好为1。

解法:

​ 首先确定0和2的相对位置如下:0,0,0,……,0,0,2,2,……,2,2。此时1可放在任意两数之间,3只能放在两个2之间或放在最右侧,故只要最大化可以放3的放置,剩余位放1即可。

​ 于是有以下的贪心策略:以最小或次小的数作为首项,设前一位放置数字x,若x-1的数量不为0就放置x-1,否则放置x+1,若x+1的数量为0则无解。

​ 复杂度: O ( n ) O(n)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int ans[maxn],a[5],tmp[5];
bool check(int fst,int n)
{
	int pt=fst;
	for(int i=0;i<4;i++)
		tmp[i]=a[i];
	if(!tmp[fst]) return false;
	for(int i=1;i<=n;i++)
	{
		ans[i]=pt,tmp[pt]--;
		if(i==n) break;
		if(pt&&tmp[pt-1]) pt--;
		else if(tmp[pt+1]) pt++;
		else return false;
	}
	return true;
}
int main()
{
	int n=0;
	for(int i=0;i<4;i++)
		scanf("%d",&a[i]),n+=a[i];
	for(int i=0;i<4;i++) if(check(i,n))
	{
		puts("YES");
		for(int j=1;j<=n;j++)
			printf("%d ",ans[j]);
		return 0;
	}
	puts("NO");
}

1265F Beautiful Bracket Sequence (ev)(区间DP)

题意:

​ 给一个仅由’?’、’(’、’)‘组成的字符串S,其中每一个’?‘均可被替换为’(’、’)’,求所有可能的全部’?'被替换后形成的字符串的括号嵌套深度之和,替换后形成的字符串不一定是合法的括号序列 ( S 2000 ) (|S|\le2000)

解法:

​ 考虑区间DP,设 d p [ l ] [ r ] dp[l][r] 为串 S l , S l + 1 , . . . , S r 1 , S r S_l,S_{l+1},...,S_{r-1},S_r 替换后形成的所有串的括号嵌套深度之和。现求 d p [ l ] [ r ] dp[l][r] 的值,对 S l S_l S r S_r 进行讨论,有如下的转移方程:

  1. S l = = ) S_l==')' ,则 S l S_l 一定不对答案产生贡献: d p [ l ] [ r ] = d p [ l + 1 ] [ r ] dp[l][r]=dp[l+1][r]
  2. S r = = ( S_r=='(' ,同理有: d p [ l ] [ r ] = d p [ l ] [ r 1 ] dp[l][r]=dp[l][r-1]
  3. S l = = ( S_l=='(' S r = = ) S_r==')' ,我们已知 d p [ l + 1 ] [ r 1 ] dp[l+1][r-1] ,仅需考虑 S l S_l S r S_r 两端对答案的贡献。设 T = S l + 1 , S l + 2 , . . . , S r 2 , S r 1 T=S_{l+1},S_{l+2},...,S_{r-2},S_{r-1} ,k为T中’?‘的数量,则当T中所有的’?'被替换后将形成 2 k 2^k 种不同的串,故 S l S_l S r S_r 的贡献为 2 k 2^k d p [ l ] [ r ] = d p [ l + 1 ] [ r 1 ] + 2 k dp[l][r]=dp[l+1][r-1]+2^k
  4. S l = = ? S_l=='?' S r = = ) S_r==')' S l S_l 能被替换为’(‘或’)’,故产生两种新串。当 S l = = ) S_l==')' 时,整个串对答案的贡献同1. ,为 d p [ l + 1 ] [ r ] dp[l+1][r] ;当 S l = = ( S_l=='(' 时,整个串对答案的贡献同3. ,为 d p [ l + 1 ] [ r 1 ] + 2 k dp[l+1][r-1]+2^k 。因此有: d p [ l ] [ r ] = d p [ l + 1 ] [ r ] + d p [ l + 1 ] [ r 1 ] + 2 k dp[l][r]=dp[l+1][r]+dp[l+1][r-1]+2^k
  5. S l = = ( S_l=='(' S r = = ? S_r=='?' ,分析同上有: d p [ l ] [ r ] = d p [ l ] [ r 1 ] + d p [ l + 1 ] [ r 1 ] + 2 k dp[l][r]=dp[l][r-1]+dp[l+1][r-1]+2^k
  6. S l = = ? S_l=='?' S r = = ? S_r=='?' ,产生四种新串。当 S l = = ) S_l==')' 时, S r = = ( S_r=='(' S r = = ) S_r==')' 两种串产生的贡献之和为 d p [ l ] [ r 1 ] dp[l][r-1] ;同理,当 S r = = ( S_r=='(' 时, S l = = ( S_l=='(' S l = = ) S_l==')' 两种串产生的贡献之和为 d p [ l + 1 ] [ r ] dp[l+1][r] 。根据上述讨论我们将 S l = = ) S_l==')' S r = = ( S_r=='(' 的情况计算了两次,但没计算 S l = = ( S_l=='(' S r = = ) S_r==')' 的情况。再由3. 的分析,我们得到当 S l = = ( S_l=='(' S r = = ) S_r==')' 时的贡献为 d p [ l + 1 ] [ r 1 ] + 2 k dp[l+1][r-1]+2^k ,而 d p [ l + 1 ] [ r 1 ] dp[l+1][r-1] 其实就是当 S l = = ) S_l==')' S r = = ( S_r=='(' 时的贡献。综上有: d p [ l ] [ r ] = d p [ l ] [ r 1 ] + d p [ 1 + 1 ] [ r ] + 2 k dp[l][r]=dp[l][r-1]+dp[1+1][r]+2^k

​ 复杂度: O ( n 2 ) O(n^2)

扫描二维码关注公众号,回复: 8903765 查看本文章
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e3+5;
const ll mod=998244353;
ll dp[maxn][maxn],cnt[maxn],pow2[maxn]={1};
char s[maxn];
int main()
{
	cin>>(s+1);
	int n=strlen(s+1);
	for(int i=1;i<=n;i++)
		cnt[i]=cnt[i-1]+(s[i]=='?'),pow2[i]=(pow2[i-1]<<1)%mod;
	for(int i=2;i<=n;i++)
		for(int l=1,r=l+i-1;r<=n;l++,r++)
		{
			ll &x=dp[l][r],p=pow2[cnt[r-1]-cnt[l]];
			x=dp[l+1][r-1];
			if(s[l]==')') x=dp[l+1][r];
			if(s[r]=='(') x=dp[l][r-1];
			if(s[l]=='('&&s[r]==')') x=dp[l+1][r-1]+p;
			if(s[l]=='?'&&s[r]==')') x=dp[l+1][r]+dp[l+1][r-1]+p;
			if(s[l]=='('&&s[r]=='?') x=dp[l][r-1]+dp[l+1][r-1]+p;
			if(s[l]=='?'&&s[r]=='?') x=dp[l][r-1]+dp[l+1][r]+p;
			x%=mod;
		}
	cout<<dp[1][n]<<endl;
}
发布了5 篇原创文章 · 获赞 3 · 访问量 128

猜你喜欢

转载自blog.csdn.net/weixin_43899905/article/details/103600067