首页 > 其他分享 >2024.1.6做题总结

2024.1.6做题总结

时间:2024-01-06 18:44:25浏览次数:23  
标签:总结 2024.1 ch int bucket read while 做题 MAXN

luogu2258 [NOIP2014 普及组] 子矩阵
本题乍一看数据范围很小,但是如果暴力的话时间复杂度为 \(O(C^r_nC^c_m)\),在最坏情况(\(r=\frac{1}{2}n,c=\frac{1}{2}m\))下过不了。

本题满足最优化,但是没得贪,二维好像不好跑 dp 啊。
可以枚举哪些行,然后跑一维的 dp。

我们用一个 dfs 固定一下每次考虑哪些行,然后将每列的行间差的和求出来,用一个 dp[i][j] 代表在第 \(i\) 列选了 \(j\) 列的最小代价,然后进行转移即可。

做法是 \(O(C^r_nn^3)\) 的,可以通过。

代码如下。

#include<bits/stdc++.h>
using namespace std;
constexpr int MAXN=16+5,MAXM=16+5;
int n,m,r,c,a[MAXN][MAXM],ans=0x3f3f3f3f,hang[MAXN],lc[MAXM],dp[MAXM][MAXM];
bool vis[MAXN];
template<typename T>
T read(){
	T 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^48);ch=getchar();}
	return f*x; 
}
namespace sol{
	int calc(int x,int y){
		int ret=0;
		for(int i=1;i<=r;++i){
			ret+=abs(a[hang[i]][y]-a[hang[i]][x]);
		}
		return ret;
	}
	void dfs(int dep,int lst){
		if(dep>=r){
			memset(dp,0x3f,sizeof(dp));
			for(int i=1;i<=m;++i)dp[i][1]=lc[i];
			for(int i=2;i<=m;++i){
				for(int j=2;j<=min(i,c);++j){
					for(int k=j-1;k<i;++k){
						dp[i][j]=min(dp[k][j-1]+calc(k,i),dp[i][j]);
					}
					dp[i][j]+=lc[i];
				}
				ans=min(ans,dp[i][c]);
			}
		}
		for(int i=lst+1;i<=n;++i){
			if(!vis[i]){
				vis[i]=1;
				hang[dep+1]=i;
				for(int j=1;j<=m;++j){
					lc[j]+=abs(a[hang[dep]][j]-a[i][j]);
				}
				dfs(dep+1,i);
				for(int j=1;j<=m;++j){
					lc[j]-=abs(a[hang[dep]][j]-a[i][j]);
				}
				vis[i]=0;
			}
		}
	}
	void solve(){
		n=read<int>();m=read<int>();r=read<int>();c=read<int>();
		for(int i=1;i<=n;++i){
			for(int j=1;j<=m;++j){
				a[i][j]=read<int>();
			}
		}
		for(int i=1;i+r-1<=n;++i){
			hang[1]=i;
			vis[i]=1;
			dfs(1,i);
			vis[i]=0;
		}
		printf("%d\n",ans);
	}
}
int main(){
	sol::solve();
	return 0;
}

当遇到一些二维之类的难处理的信息的时候,不妨用枚举将信息简化一下,可能会存在更优的做法。

[ABC293G] Triple Index

第一次写莫队。
题解里都说应该作为莫队的板子,我觉得是这样的。
组合数学不好,同学帮忙才过,怄火。

没啥好的数据结构可以在线维护这个问题。
但是如果在暴力的基础上,开个桶统计每个数出现次数求得一个区间的答案,把区间的左右两端加上或删去一个数的话转移是 \(O(1)\) 的。

如果用莫队的话,这个题的复杂度是 \(O(n\sqrt n)\)。

组合数部分,因为我比较菜,一开始考虑 \(C^m_n=\frac{n!}{m!(n-m)!}\),还有怕溢出,所以用 C[i]=C[i-1]/(i-3)*i 转移的。
然而不一定存在 \((i-3)\mid C^3_{i-1}\)。
除法和乘法换过来没爆掉的话正确性可以保证,爆掉就不能保证。
后来 lzc 给我换了 C[i]=i*(i-1)*(i-2)/6;
过了。

代码如下。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr int MAXN=2e5+10;
ll C[MAXN];
int n,a[MAXN],Q,bucket[MAXN],tl,tr;
ll ans[MAXN],tans;
struct query{
	int l,r,id;
}q[MAXN]; 
template<typename T>
T read(){
	T x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9'){ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
	return x;
}
namespace sol{
	bool cmp1(query x,query y){return x.l<y.l;}
	bool cmp2(query x,query y){return x.r<y.r;}
	void C_init(){
		C[0]=C[1]=C[2]=0;
		C[3]=1;
		for(ll i=4;i<MAXN;++i){
			C[i]=i*(i-1)*(i-2)/6;
		}
	}
	void solve(){
		sol::C_init();
		n=read<int>();Q=read<int>();
		for(int i=1;i<=n;++i)a[i]=read<int>();
		for(int i=1;i<=Q;++i){
			q[i].l=read<int>();q[i].r=read<int>();q[i].id=i;
		}
		sort(q+1,q+Q+1,sol::cmp1);
		int T=sqrt(Q);
		for(int i=1;i<=T;++i){
			sort(q+(i-1)*T+1,q+i*T+1,sol::cmp2);
		}
		if(T*T!=Q)sort(q+T*T+1,q+Q+1,sol::cmp2);
		tl=tr=1;++bucket[a[tl]];
		for(int i=1;i<=Q;++i){
			while(tl>q[i].l){
				--tl;
				++bucket[a[tl]];
				tans+=C[bucket[a[tl]]]-C[bucket[a[tl]]-1];
			}
			while(tr<q[i].r){
				++tr;
				++bucket[a[tr]];
				tans+=C[bucket[a[tr]]]-C[bucket[a[tr]]-1];
			}
			while(tl<q[i].l){
				tans-=C[bucket[a[tl]]]-C[bucket[a[tl]]-1]; 
				--bucket[a[tl]];
				++tl;
			}
			while(tr>q[i].r){
				tans-=C[bucket[a[tr]]]-C[bucket[a[tr]]-1]; 
				--bucket[a[tr]];
				--tr;
			}
			ans[q[i].id]=tans;
		}
		for(int i=1;i<=Q;++i){
			printf("%lld\n",ans[i]);
		}
	}
}
int main(){
	sol::solve();
	return 0;
}

莫队可以用在一些在线没思路但是查询转移比较简单的题中。

luogu1570 KC 喝咖啡

复习下二分。
做题的时候卡精度了,下次精确到 \(x\) 位小数的时候 \(eps\) 设为 \(1^{-x-2}\)。

这道题可能会有一个贪心的想法,每次选择 \(\frac{v_i}{c_i}\) 最大的,但是这个贪心假了。
反例:

3 2
1000 10
1000 100
1 1

这个题直接做不好做,但是判定很简单。
我们可以检验 \(\frac{\sum v_i}{\sum c_i}\) 与一个数 \(x\) 的关系。
两个式子同时乘 \(\sum c_i\) 就转化成检验 \(\sum v_i\) 与 \(x\times\sum c_i\) 的关系。
我们可以对于每个调料计算其 \(v_i-x\times c_i\) 的值,然后排序选取这个值大的调料,最后判断这些值的和是否大于等于 \(0\) 即可。
然后上个二分就做完了。

好像可以用 01 分数规划做,但是我不会。

代码如下。

#include<bits/stdc++.h>
using namespace std;
constexpr int MAXN=200+10;
constexpr double eps=1e-5;
int n,m;
struct item{
	int v,c;
	double val;
}it[MAXN];
template<typename T>
T read(){
	T 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^48);ch=getchar();}
	return f*x;
}
namespace sol{
	bool cmp(item x,item y){return x.val>y.val;}
	void solve(){
		n=read<int>();m=read<int>();
		for(int i=1;i<=n;++i){
			it[i].v=read<int>();
		}
		for(int i=1;i<=n;++i){
			it[i].c=read<int>();
		}
		double l=0,r=2e6+10;
		while(r-l>eps){
			double mid=(l+r)/2;
			for(int i=1;i<=n;++i){
				it[i].val=it[i].v-it[i].c*mid;
			}
			sort(it+1,it+n+1,cmp);
			double tot=0;
			for(int i=1;i<=m;++i){
				tot+=it[i].val;
			}
			if(tot>0){
				l=mid;
			}
			else if(tot==0)r=l=mid;
			else{
				r=mid;
			}
		}
		printf("%.3lf",l);
	}
}
int main(){
	sol::solve();
	return 0;
}

这种最优化的题可能是二分做法,对于一些式子可以将其转化一下,也许可以得到一个简单的判定,然后用二分可以做出。

标签:总结,2024.1,ch,int,bucket,read,while,做题,MAXN
From: https://www.cnblogs.com/LiJoQiao/p/17949363

相关文章

  • 多线程(互斥锁,条件变量,虚假唤醒)知识点总结
    互斥锁mutexC++11一共提出四种互斥锁std::mutex:独占的互斥锁,不能递归使用std::timed_mutex:带超时的独占互斥锁,不能递归使用std::recursive_mutex:递归互斥锁,不带超时功能std::recursive_timed_mutex:带超时的递归互斥锁1.mutexmutex有三个成员函数:voidlock();booltry_loc......
  • Solution Set【2024.1.5】
    明天再补。[POI2011]LightningConductor设\(f_i\)表示只考虑\(\left[1,i\right]\)的情况下\(i\)的答案,那么有:\[f_i=\max\limits_{j\lei}a_j-a_i+\sqrt{\left\lverti-j\right\rvert}\]发现其满足四边形不等式,于是使用分治优化即可。时间复杂度\(O(n\log......
  • sentinel总结
    限流降级在微服务系统中,一个对外的业务功能可能会涉及很长的服务调用链路。当其中某个服务出现异常,如果没有服务调用保护机制可能会造成该服务调用链路上大量相关服务直接或间接调用的服务器仍然持续不断发起请求,最终导致相关的所有服务资源耗尽产生异常发生雪崩效应。限流和降......
  • 2023 年终总结
    这一年的情况AtCoder等级分860分,参加16场rating。于今年9.30开始打。每一场abc和arc几乎都有打。performance最高是:link。切了ABCDE。也打了一些VP:2023.12.6ABC312VP(OI赛制)2023.12.9ABC301VP(OI赛制)2023.12.10ABC321VP(IOI赛制...2023.12.12ABC320VP(IOI赛制...20......
  • 2024.1.5——每日总结
    学习所花时间(包括上课):9h代码量(行):0行博客量(篇):1篇今天,上午学习,下午学习;我了解到的知识点:1.ERP明日计划:学习......
  • 2023-2024-1 20231307 《计算机基础与程序设计》第七周学习总结
    作业信息这个作业属于哪个课程2023-2024-1-计算机基础与程序设计这个作业要求在哪里2023-2024-1计算机基础与程序设计第七周作业这个作业的目标数组与链表、基于数组和基于链表实现数据结构、无序表与有序表、树、图、子程序与参数作业正文https://www.cnblogs.c......
  • 2023-2024-1 20231312 《计算机基础与程序设计》第十五周学习总结
    作业信息这个作业属于哪个课程<班级的链接>2023-2024-1-计算机基础与程序设计|-这个作业要求在哪里<作业要求链接>2023-2024-1计算机基础与程序设计第6周作业|这个作业的目标课程总结|作业正文作业链接第一周目标:课程概论,工业革命与浪潮之巅,信息与信......
  • Spring总结
    Spring框架1、简介Spring:春天---->给软件行业带来了春天2002:首次推出了Spring框架的雏形spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日发布1.0正式版.RodJohnson,springframework创始人,很难想象这个人的学历,他学音乐学Sprin......
  • 南外集训 2024.1.5 T3
    非常简单的一道题。要好好反思为什么没有做出来。题意给定一棵点带权的树,强制在线询问一条链上取恰好\(m\)个数按位与的最大值。\(1\len\le10^6,1\leq\le10^5,1\lem\le10,0\leV<2^{62}\)。解法考虑一个暴力:取出树链上所有点权,二分答案\(x\),则需要检查是否存在至......
  • MySQL高性能优化规范建议总结
    1、优先选择符合存储需要的最小的数据类型,因为存储字节越小,占用也就空间越小,性能也越好。a.某些字符串可以转换成数字类型存储比如可以将IP地址转换成整型数据。b.对于非负型的数据(如自增ID,整型IP,年龄)来说,要优先使用无符号整型来存储。c.小数值类型(比如年龄、状态表......