首页 > 其他分享 >P9572 Colorful Days♪

P9572 Colorful Days♪

时间:2023-08-22 19:48:07浏览次数:34  
标签:P9572 Colorful int 代码 Days mid 数组 c2 c1

思路

Step0.骗分

显然,题目中的 \(c_1,c_2\) 就是为了送分,如果比赛中没有思路,倒是可以直接输出两个 \(0\) 先得到 \(2\) 分,聊胜于无。

Step1.暴力不出奇迹

显然第一个想到的是暴力,枚举 \(k\),容易观察得出,若一次增加 \(k\) 而 LCS 不变,则再增加 \(k\) 也无用。可凭借这个结论暴力验证,然后得出答案。

但是非常显然,这样时间复杂度及其高,定然会 TLE。

Step2.观察性质

我们发现,如果 \(k\) 足够大,那么所有同时存在于数组 \(S,T\) 的数字都可以贡献答案,所以最大的 \(LCS\) 就是同时存在数组 \(S,T\) 的个数。

Step3.从模拟入手

想要直接找到最小 \(k\) 不是一件简单的事情,不如逐步模拟。

因为我们在 Step2 中得出结论,只要是同时存在于数组 \(S,T\) 的,都需要计算,所以我们可以遍历数组 \(T\)。

假设当前遍历到的数是 \(x\)。

如果 \(x\) 不在数组 \(S\) 中,则可以直接跳过,因为无论 \(k\) 多大,也没有任何用处。

如果 \(x\) 在数组 \(S\) 中,那么就可以贡献答案,如果前一个可贡献答案的数在数组 \(S\) 中的位置之后有 \(x\) 的话,那么不需要增加 \(k\),如果没有的话,则需要增加一次 \(k\),用新增加的一段中的 \(x\) 满足要求。

这样就完美地解决了 \(k\) 的问题。

Step4.代码写法

可以用 vector 储存每个数字在数组 \(S\) 中的位置。

用一个变量,储存上一个可贡献答案的数在数组 \(S\) 中的位置。

我们就只需要遍历 vector,找到位置之后的满足条件的坐标,如果找不到,就增加 \(k\),并把变量赋值为该数字第一次出现的位置。

AC 代码

#include<bits/stdc++.h>
using namespace std;
int n,m,c1,c2,s[1000005],t[1000005],res,k=1,p,cnt;
vector<int>v[1000005];
int main()
{
	scanf("%d%d%d%d",&n,&m,&c1,&c2);
	for(int i=1;i<=n;++i) scanf("%d",&s[i]),v[s[i]].push_back(i);
	for(int i=1;i<=m;++i) scanf("%d",&t[i]);
	for(int i=1;i<=m;++i)
	{
		if(!v[t[i]].size()) continue;//如果在S中不存在就直接跳过
		else
		{
			int flag=0;res++;//用flag标记是否找到位置
			for(int j=0;j<v[t[i]].size();++j) if(v[t[i]][j]>p){flag=1,p=v[t[i]][j];break;}//找到第一个大于p的位置
			if(!flag) k++,p=v[t[i]][0];//没找到就需要增加k了,记得赋值
		}
	}
	printf("%d %d",res*c1,k*c2);//别忘了乘以c1,c2
	return 0;
}

题外话

这个代码其实有个小问题,如果 LCS 为 \(0\),那么非负整数 \(k\) 的最小值应该是 \(0\)。只不过因为太细节,加了可能会影响公平性,所以没加。

改代码也很简单,只需要判断 \(res\) 是不是 \(0\) 就好。这里不改是看看到时候会不会有人直接复制交(滑稽)。

Step5.进一步的优化

原本交了,但是被巨佬同学说了,我这个复杂度过了是因为数据水,所以我有屁颠屁颠地跑回来修改了。

显然如果数据构造合适,在查找位置的时候会被卡,所以考虑在查找优化时间复杂度,第一时间就想到是二分。绝对不是看到标签里有二分。

这样的话就容易了,只需要再写个二分查找就好了。

仅贴出部分代码(二分查找函数和调用部分的循环代码)

int find(int i,int x)
{
	int l=0,r=v[i].size()-1,mid,ans=-1;
	while(l<=r)
	{
		mid=l+r>>1;
		if(v[i][mid]>x) r=mid-1,ans=v[i][mid];
		else l=mid+1;
	}
	return ans;
}
/////////////
for(int i=1;i<=m;++i)
{
	if(!v[t[i]].size()) continue;
	else
	{
		int l=find(t[i],p);res++;
		if(l==-1) k++,p=v[t[i]][0];
		else p=l;
	}
}

标签:P9572,Colorful,int,代码,Days,mid,数组,c2,c1
From: https://www.cnblogs.com/One-JuRuo/p/17649517.html

相关文章

  • [刷题笔记] [【LGR-155-Div.3】T4] Luogu P9572 「NnOI R2-T4」Colorful Days♪
    ProblemDescription有两个数组\(A,B\),我们可以将\(A\)数组无限次重复拼接。求最少需要多少次拼接使得拼接后的\(A,B\)的最长公共子序列最大。Analysis我们要学会从题目中找到一些信息,比如说本题的数据范围:对于\(100\%\)的数据,保证\(1\leqn,m,S_i,T_i\le10^6\),\(......
  • Rocky虚拟机(Three Days)用户与组管理与目录/文件权限
    ThreeDays一、用户管理1、概述Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统用户的账号一方面可以帮助系统管理员对使用系统的用户进行跟踪,并控制他们对系统资源的访问;另一方......
  • P9572 Colorful Days♪ 题解
    原题链接题目大意:有两个数组\(S\),\(T\),你可以把\(S\)进行复制并接到其后面形成\(S^k\),如\(S\)=123,则\(S^2\)=123123,\(S^3\)=123123123。让你求出\(S^k\)与\(T\)的最长公共子序列以及在最长公共子序列最长时\(k\)的最小值。首先思考如果无视\(k\)最小的要求,最......
  • Learn Git in 30 days——第 04 天:常用的 Git 版本控制指令
    写的非常好的一个Git系列文章,强烈推荐原文链接:https://github.com/doggy8088/Learn-Git-in-30-days/tree/master/zh-cn本篇文章将带大家学会几个最重要也最基本的版控工作,其中将包含基本的文件操作如新增、删除、重新命名文件,提交变更(建立新版本)、查询历史记录等工作。准......
  • Learn Git in 30 days——第 02 天:在 Windows 平台必装的三套 Git 工具
    写的非常好的一个Git系列文章,强烈推荐原文链接:https://github.com/doggy8088/Learn-Git-in-30-days/tree/master/zh-cn要开始使用Git版本控制,首先要安装适当的Git工具,这个系列的文章主要还是以Windows平台为主,这篇文章将会介绍三套我们最常用的Git版控工具,并介绍这几......
  • Learn Git in 30 days——第 01 天:认识 Git 版本控制
    写的非常好的一个Git系列文章,强烈推荐原文链接:https://github.com/doggy8088/Learn-Git-in-30-days/tree/master/zh-cn笔者使用Subversion(SVN)已经将近10年,从来都不觉得有任何必要换成其他版本控制平台,直到前几年因为云端化的改变,慢慢转成TFS版本控制(TFSService),转......
  • AT_apc001_g Colorful Doors 题解
    模拟赛做到的题,场上写贪心爆栈了qwq首先在首尾加上两个\(1\)表示进出,将两段路中间的间隔作为传送门,恰好有\(2\timesN\)个传送门,根据两段路的经过情况给传送门分类别:00:用\(N\)表示,称为无用点,不到达该点。10:用\(S\)表示,称为起点,需要通过向右走走到一次。01:用\(T\)......
  • LeetCode 1011. Capacity To Ship Packages Within D Days 二分答案
    Aconveyorbelthaspackagesthatmustbeshippedfromoneporttoanotherwithindaysdays.Theithpackageontheconveyorbelthasaweightof\(weights[i]\).Eachday,weloadtheshipwithpackagesontheconveyorbelt(intheordergivenby\(wei......
  • AtCoder Grand Contest 012 D Colorful Balls
    洛谷传送门AtCoder传送门不错的题。bxEnder32k。我们发现交换有传递性,那么我们能交换就连边,答案是\(\prod\frac{(sz)!}{\prodc_i!}\),其中\(sz\)为连通块大小,\(c_i\)为这个连通块中第\(i\)种颜色出现次数。于是我们得到了一个\(O(n^2)\)的做法。发现很多遍是无用的......
  • NC200179 Colorful Tree
    题目链接题目题目描述Atreestructurewithsomecolorsassociatedwithitsverticesandasequenceofcommandsonitaregiven.Acommandiseitheranupdateoperationoraqueryonthetree.Eachoftheupdateoperationschangesthecolorofaspecifiedvert......