首页 > 其他分享 >1733D1&D2解题报告

1733D1&D2解题报告

时间:2022-09-21 20:13:19浏览次数:47  
标签:ch return int long 解题 D2 1733D1 dp lld

1733D1

题目大意:给出两个长度为n的01串,每次能选择两个位置进行取反,相邻的位置取反代价为x,不相邻则为y,问让其中一串变成另一串的最小代价

初遇想法

对于两个串上01不同的位置可以直接发现

相邻代价为$min$($x$,$y/times2$)

不相邻代价为$min$($x/times$两点距离,$y$)

并且若01不同的位置是奇数显然无解

由于直接忽略了题给的$x$和$y$的大小条件,以至于我陷入了D2的思考。

考虑贪心,每两个点直接进行代价的判断

显然最后为了纠正这个错误的想法花了相当大的力气

further

根据题给条件,发现出题人希望让我们去多使用不相邻的两点

反思和提醒之后发现,把视线只放在两点是很局限的一种判断

只要超过三个点,我们可以直接跨点构造出不相邻

结论

特判长度是否为2,即无法构造不不相邻

否则全部构造成不相邻

代码如下

#include <bits/stdc++.h>
using namespace std;
int a[100000],b[100000];
vector<int> s;
int read()
{
	int ret(0);
	char ch=getchar();
	while (ch!='0'&&ch!='1') ch=getchar();
	return ch-48;
}
int main()
{
	int t;
	scanf("%d",&t);
	while (t--)
	{
		s.clear();
		long long n,x,y;
		scanf("%lld%lld%lld",&n,&x,&y);
		for (int i=1;i<=n;i++) a[i]=read();
		for (int i=1;i<=n;i++) b[i]=read();
		for (int i=1;i<=n;i++)
			if (a[i]!=b[i]) s.push_back(i);
		int len=s.size()-1;long long ans(0);
		if ((len+1)%2==0)
		{
			if (len+1>2) printf("%lld\n",y*(len+1)/2);
			else 
			{
				if (len+1==0) printf("0\n");
				else if (s[0]+1==s[1]) printf("%lld\n",min(y*2,x));
				else printf("%lld\n",y);
			}
		}
		else printf("-1\n");
	}
	return 0;
}

1733D2

$n^3dp$很显然

$n^3$的问题在于枚举断点,联系上一题,长度大于4,就可以强行构造不相邻,所以断点是长度为4的时候

$n^2$dp即可

#include <bits/stdc++.h>
using namespace std;
int a[100000],b[100000];
vector<int> s;
long long x,y;
long long dp[5010][5010]; 
long long solve(int a,int b)
{
	if (a+1==b) return min(x,y*2);
	else return min(x*(b-a),y);   
}
int read()
{
	int ret(0);
	char ch=getchar();
	while (ch!='0'&&ch!='1') ch=getchar();
	return ch-48;
}
int main()
{
	int t;
	scanf("%d",&t);
	while (t--)
	{
		s.clear();
		long long n;
		scanf("%lld%lld%lld",&n,&x,&y);
		for (int i=1;i<=n;i++) a[i]=read();
		for (int i=1;i<=n;i++) b[i]=read();
		s.push_back(0);
		for (int i=1;i<=n;i++)
			if (a[i]!=b[i]) s.push_back(i);
		int len=s.size()-1;
		for (int i=1;i<=len;i++)
		for (int j=1;j<=len;j++) 
		dp[i][j]=0x3f3f3f3f3f3f3f3f;
		//printf("len=%d\n",len);
		if (len==0) printf("0\n");
		else
		{
			if (len&1) printf("-1\n");
			else
			{
				for (int i=1;i<len;i++) 
					dp[i][i+1]=solve(s[i],s[i+1]);
			//	for (int i=1;i<len;i++)
			//		printf("%d %d %lld\n",i,i+1,dp[i][i+1]);
				for	(int i=3;i<len;i+=2)
				{
						for (int l=1;l<=len-i;l++)
						{
							int r=l+i;
							//printf("%d %d %dQQQ\n",l,r,i);
							dp[l][r]=min(dp[l][r-2]+solve(s[r-1],s[r]),dp[l+2][r]+solve(s[l],s[l+1]));
							dp[l][r]=min(dp[l][r],dp[l+1][r-1]+solve(s[l],s[r]));
							dp[l][r]=min(dp[l][r],y*(r-l+1)/2);  
							if (len>=5) dp[l][r]=min(dp[l][l+3]+dp[l+4][r],dp[l][r]);
							
						}
				}
				printf("%lld\n",dp[1][len]);
			}
		}
	}
	return 0;
}

标签:ch,return,int,long,解题,D2,1733D1,dp,lld
From: https://www.cnblogs.com/by-w/p/16716969.html

相关文章

  • Codeforces Round #821 (Div. 2) - D2. Zero-One (Hard Version)
    区间DPProblem-D2-Codeforces题意给一个长度为\(n(5<=n<=5000)\)的01串,每次操作可选择一个\(l,r(l<r)\),把\(s[l],s[r]\)反转。如果\(l+1==r\),花费为x,否......
  • P8283 「MCOI-08」Dantalion 解题报告
    P8283「MCOI-08」Dantalion解题报告:最近好像有很多人做这道题,把这题题解发一下吧。可能说的比较啰嗦,见谅。题意给定序列\(a\),\(q\)次询问一个区间有多少个子区间在......
  • D2. Zero-One (Hard Version)
    题意给定\(n,x,y\)和两个01串,字符串的长度为\(n\),现在你可以选择一个\(l\)和\(r\)(\(1\leq{l}<{r}\leq{n}\)),将\(a_l\)变成\(1-a_l\),将\(a_r\)变成\(1-a_r\),\(l+1=r\),则代......
  • Codeforces Round #821 D2
    D2.Zero-One(HardVersion)我们由D1可知当我们的y小于x/2时我们可以用2y来减小相邻的cost那我们考虑要是y比较大的时候我们也可以用多个x来减小cost我们可以轻松的......
  • Codeforces #821 Div2(A~D2)题解
    CF#821Div2AConsecutiveSum题目:​ 选择\(i\)和\(j\),如果\(j=i+xk(x=R)\),可以交换\(i,j\)。任意选择一段长度为k的相加。思路:​ 题目等价于在下标\(mod\)k相同......
  • 【解题报告】[JOISC 2014] 挂饰
    【我也不知道什么TM的系列】JOISC2014挂饰经典的传送门写这篇文章来告诉大家写贪心的重要性心路历程看到这道题第一印象:woc蓝题看了一下样例:woc水题贪了60分:woc......
  • 【解题报告】Power收集
    东方Project相关试题Power收集(注:我不是东方众哦但下次回家可以试着玩一下传送门先读题啦n*m矩阵,其中有K个格子上有P点,价值val[i][j],从第一行任意格子出发,每秒向下走......
  • 【Coel.解题报告】【没事找事】CSP-S2 真题解析
    昨天刚考完CSP-S1,反正没什么想做的(最近好颓废…),来复盘一下。本次比赛评价(转载):CSP-S1是由CCF自主研发的一款全新开放世界冒险游戏。游戏发生在一个被称作「基数排序......
  • P7856 「EZEC-9」模糊众数 解题报告
    P7856「EZEC-9」模糊众数解题报告:题意给定一个长度为\(n\)的序列,一次操作可以将某个数字加一,多次询问一个数\(x\),求使得\(x\)称为序列众数至少要多少次操作。\(1......
  • ARC147F Again ABC String 解题记录
    题意:给定整数\(X,Y,Z\),称一个字符串\(S\)合法,当且仅当:\(|S|=n\)仅由字符\(\texttt{A,B,C}\)构成。对每个\(i\)满足:记\(A_i,B_i,C_i\)表示\(S\)前\(i\)......