2021.11.4模拟总结

前言

崩盘。。。(30+10+0+20=60pts)
找一下原因吧。
大概是因为把 (T1) 想的过于复杂,时间长。
加上略微有点困,看完 (T1) 就有点没有动力了,感觉整场考试都是半麻的状态(没有那种世俗的欲望.jpg)。
当然这肯定是不行的,想不出来的时候不妨换个思路嘛,这种把精神状态都搭进去的思考就没太大价值了。
以至于 (T4) 最后已经想到了关键点,但是就是由于思维不够活络而没进一步思考。
真的需要提高兴奋度,专注度,紧张度。
算是吸取了经验教训吧。

T1 coin

题意:宽度为 (k) 的爪子抓硬币,不能抓空。

分析

最 TM 离谱的题,这么简单的 DP 我都没做出来。
一开始也想到 DP,但是转移的时候本来想的是从前面的所有位置转移过来,但是这样会重复;又想从 (i-k) 的位置转移过来,又会漏算中间的部分。于是我就以为这个后效性没法处理,于是想别的思路,然后就 gg 了。
实际上,只有 (mod k) 相同的位置互相有影响,奇数个就少选一个最小的,偶数个就全选(这甚至不需要 DP)。
但其实 DP 也可以,只需要把中间的部分从 (i-1) 继承过来即可,相当于前缀和的思想。
其实方法还有很多,但我一个都没有想到QAQ

代码

点击查看代码
#include <bits/stdc++.h>
#define fo(a) freopen(a".in","r",stdin), freopen(a".out","w",stdout)
using namespace std;
const int INF = 0x3f3f3f3f, N = 1e5+5;
typedef long long ll;
typedef unsigned long long ull;
inline ll read(){
	ll ret = 0; char ch = ' ', c = getchar();
	while(!(c >= '0' && c <= '9')) ch = c, c = getchar();
	while(c >= '0' && c <= '9') ret = (ret << 1) + (ret << 3) + c - '0', c = getchar();
	return ch == '-' ? -ret : ret;
}
int n,m;
ll a[N];
ll dp[N][2];
int len;
signed main(){
	//fo("coin");
	n = read(), m = read();
	for(int i = 1 ; i <= n ; i ++)
		a[i] = read();
	for(int i = m+1 ; i <= n ; i ++){
		dp[i][0] = dp[i][1] = max(dp[i-1][0],dp[i-1][1]);
		dp[i][1] += -max(dp[i-m][0],dp[i-m][1]) + dp[i-m][0] + a[i] + a[i-m];
	}
	printf("%lld",max(dp[n][0],dp[n][1]));
}
/*
3 2
1 2 3
-------
5 2
1 2 3 2 1
*/

T2 maze

分析

已经想到以每个点为圆心画圆,使得上下连起来的思路。
然而对于建图出现了瓶颈。
实际上,借用最小生成树的思路,从上边界为起点,直到碰到下边界为止,最大的边就是答案。
不过,生成的可能不是树,只是借用了这种思想。
由于边数有 (n^2) 级别,所以要用 Prim,而且不能加堆优化,甚至不能存图(空间不够)

代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f,N = 6e3+10;
#define ll long long 
#define FCC fclose(stdin),fclose(stdout)
inline ll read()
{
	ll ret=0;char ch=' ',c=getchar();
	while(!(c>='0'&&c<='9')) ch=c,c=getchar();
	while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
	return ch=='-'?-ret:ret;
}
int n,m,k;
ll x[N],y[N];
inline double sq(int i,int j)
{
	return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
int head[N],ecnt=-1;
void init_edge(){memset(head,-1,sizeof(head)),ecnt=-1;}
struct edge
{
	int nxt,to;
	double w;
}a[N*N<<1];
inline void add_edge(int x,int y,double w)
{
	a[++ecnt]=(edge){head[x],y,w};
	head[x]=ecnt; 
}
bool vis[N];
double dis[N],ans;
void prim()
{
	for(int i=1;i<=k+1;i++) dis[i]=1e18;
	dis[0]=0;
	while(1)
	{
		double minn=1e18;
		int u=0;
		for(int i=0;i<=k+1;i++)	
		{
			if(dis[i]<minn&&!vis[i]) minn=dis[i],u=i;
		}
		//puts("");
		if(minn==1e18) break;
		vis[u]=1;
		ans=max(ans,minn/2);
		//printf("u=%d
",u);
		if(u==k+1) {printf("%.8lf",ans);return;}
		vis[u]=1;
		for(int i=head[u];~i;i=a[i].nxt)
		{
			int v=a[i].to;
			if(dis[v]>a[i].w)
			{
				dis[v]=a[i].w;
			//	if(!vis[v]) q[++cnt]=v;
			}
		}
	}
}
signed main()
{
	n=read(),m=read(),k=read();
	init_edge();
	for(int i=1;i<=k;i++) 
	{
		x[i]=read(),y[i]=read();
		add_edge(0,i,m-y[i]),add_edge(i,0,m-y[i]);
		add_edge(k+1,i,y[i]),add_edge(i,k+1,y[i]);
	}
	for(int i=1;i<=k;i++)	 
		for(int j=1;j<i;j++)
		{
			add_edge(i,j,sq(i,j)),add_edge(j,i,sq(i,j));
		//	printf("%.8lf
",sq(i,j));
		}
	prim();
	return 0;
}

T4 锦标赛

分析

其实这题真的很好想暴力,首先排序,然后就知道可以区间 DP 了。
但是我压根没往这方面想,净想贪心,数据结构之类了(麻了)
(dp(l,r,k)) 表示用 (k) 天解决区间的最小代价,转移也就很显然了。
正解是决策单调性优化,并不容易。但是暴力没想出来属实是不应该,可能一方面不够扎实,一方面钻牛角尖了。

暴力代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f,N = 1e3+10;
#define ll long long 
#define FCC fclose(stdin),fclose(stdout)
inline ll read()
{
	ll ret=0;char ch=' ',c=getchar();
	while(!(c>='0'&&c<='9')) ch=c,c=getchar();
	while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
	return ch=='-'?-ret:ret;
}
int n,k,a[N];
int dp[N][N][51];
int solve(int l,int r,int d)
{
	if(l==r) return 0;
	if(!d) return INF;
	if(dp[l][r][d]) return dp[l][r][d];
	dp[l][r][d]=INF;
	for(int i=l;i<r;i++)	
	{
		dp[l][r][d]=min(dp[l][r][d],solve(l,i,d-1)+solve(i+1,r,d-1)+a[r]-a[i]);
	}
	return dp[l][r][d];
}
int main()
{
	n=read(),k=read();
	for(int i=1;i<=n;i++) a[i]=read();
	sort(a+1,a+n+1);
	printf("%d
",solve(1,n,k));
	return 0;
}
/*
4 3 
1 90 91 92
18 7
67 64 52 18 39 92 84 66 19 64 1 66 35 34 45 2 79 34
*/
原文地址:https://www.cnblogs.com/conprour/p/15508620.html