ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

noip模拟66

2021-10-03 07:31:23  阅读:160  来源: 互联网

标签:dm noip dh double t2 360 66 模拟 define


考试过程:可能受到了自己生病的一些影响,这次考试状态不是很好。做题的时候比较困。我按顺序开题,首先是T1,这题挺有意思,显然是一道DP题,但是刚开始我想的是类似于\(f_{i,j}\)表示第1个序列选\(i\)个,第二个序列选\(j\)个的最大值,但是这么转移不仅复杂度很高并且转移也很麻烦。我又想了想觉得可以将两个序列分开考虑,最后再合并,反正只要体积是一定的就是对的,然后就切了。
T2,这题考场上实在没什么思路,就打了个暴搜。T3,我觉得部分分挺多,但是我读错题了,导致我获得了\(0pts\)的高分...。总之,以后还是要多注意身体,生病啥的都会影响考试状态。

T1 接力比赛

思路:上面说的差不多了,我将左右两边分开考虑,我的朴素DP是\(f_{i,j}\)表示第一个序列以\(i\)结尾的总体积为\(j\)的最大值,\(g_{i,j}\)同理,那么转移是显然的\(f_{i,j}=max(f_{i,j},f_{k,j-w_i}+v_i)\),这样的复杂度是\(n^2\times U\)的,复杂度比较高,然后我观察这个DP式子,发现这好像是一个背包,然后我就按照背包DP的思路优化了一下\(f_{i,j}=max(f_{i-1,j},f{i-1,j-w_i}+v_i)\),这样就把复杂度降掉一个\(n\),然后卡卡上界这道题就切了。
代码如下:

AC_code

#include<bits/stdc++.h>
#define int long long
#define re register int
#define ii inline int
#define iv inline void
#define f() cout<<"fuck"<<endl
using namespace std;
const int N=1e6+10;
const int M=1010;
const int INF=1e18;
int n,m,ans;
int f[N],g[N],s1[N],s2[N];
struct node
{
	int w,v;
}c1[M],c2[M];
ii read()
{
	int x=0;char ch=getchar();bool f=1;
	while(ch<'0' or ch>'9')
	{
		if(ch=='-') f=0;
		ch=getchar();
	}
	while(ch>='0' and ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return f?x:(-x);
}
signed main()
{
	freopen("game.in","r",stdin),freopen("game.out","w",stdout);
	n=read(),m=read();
	for(re i=1;i<=n;i++) c1[i]=(node){read(),read()},s1[i]=s1[i-1]+c1[i].w;
	for(re i=1;i<=m;i++) c2[i]=(node){read(),read()},s2[i]=s2[i-1]+c2[i].w;
	int up=max(s1[n],s2[m]);
	for(re i=1;i<=up;i++) f[i]=g[i]=-INF;
	f[c1[1].w]=c1[1].v;
	for(re i=2;i<=n;i++)
		for(re p=s1[i];p>=c1[i].w;p--)
			f[p]=max(f[p],f[p-c1[i].w]+c1[i].v);
	g[c2[1].w]=c2[1].v;
	for(re i=2;i<=m;i++)
		for(re p=s2[i];p>=c2[i].w;p--)
			g[p]=max(g[p],g[p-c2[i].w]+c2[i].v);			
	for(re i=1;i<=up;i++) ans=max(ans,f[i]+g[i]);
	printf("%lld\n",ans);
	return 0;
}


T2 树上竞技

留坑

T3 虚构推理

思路:我在考场上看错题了,这道题其实是将时针与时针的夹角比较,分针和分针的夹角比较,然后取个\(max\),但是我直接把当前时间点的角度进行了比较。知道了题意,那我们考虑做法,首先我们可以枚举\(i,j,k\)表示时,分,秒。然后计算取最小的最大值即可。
计算的话利用一个\(upper_bound\)将排序后的数组二分查找即可。
注意1.我们要将边界设为\(a_0=a_n,a_{n+1}=a_1\),这样可以避免很多问题。
2.在计算角度的时候我们利用了\(t2=t1+180\),但是要计算夹角我们要用\(180-t2-a_p\),不能直接用\(t1-a_p\),因为这样算出来的夹角可能是钝角。
代码如下:

AC_code

#include<bits/stdc++.h>
#define re register int
#define ii inline int
#define iv inline void
#define f() cout<<"fuck"<<endl
#define head heeadd
#define next net
#define D double
using namespace std;
const int N=5e4+10;
const double eps=1e-6;
int n;
double ans=999999999.999999;
int h[N],m[N],s[N];
double du[N],dh[N],dm[N];
char ch[N];
ii read()
{
	int x=0;char ch=getchar();bool f=1;
	while(ch<'0' or ch>'9')
	{
		if(ch=='-') f=0;
		ch=getchar();
	}
	while(ch>='0' and ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return f?x:(-x);
}
signed main()
{
	freopen("unreal.in","r",stdin),freopen("unreal.out","w",stdout);
	n=read();
	for(re i=1;i<=n;i++)
	{
		scanf("%s",ch+1);
		int len=strlen(ch+1),tmp=0,flag=0;
		for(re j=1;j<=len;j++)
		{
			if(ch[j]==':')
			{
				if(flag==0) h[i]=tmp;
				else if(flag==1) m[i]=tmp;
				++flag,tmp=0;
				continue;
			}
			tmp=tmp*10+ch[j]-'0';
		}
		s[i]=tmp;
		if(h[i]>=12) h[i]=h[i]%12;
		dh[i]=(double)h[i]*30.00000+(double)m[i]*0.50000+(double)s[i]*0.5/60.0;
		dm[i]=(double)m[i]*6.00000+(double)s[i]*0.10000;
	}
	sort(dh+1,dh+n+1),sort(dm+1,dm+n+1);
	dh[0]=dh[n],dh[n+1]=dh[1];
	dm[0]=dm[n],dm[n+1]=dm[1];
	for(re i=0;i<12;i++)
	{
		for(re j=0;j<60;j++)
		{
			for(double k=0.00000;k<60;k+=0.01)
			{
				double maxx=0.000,t1,t2;
				int pos;
				
				t1=(double)i*30.0000+(double)j*0.50000+k*0.5/60.0;
				t2=t1+180.00;
				if(t2>=360) t2-=360.00;
				pos=upper_bound(dh+1,dh+n+1,t2)-dh;
				double tmp1=180-(dh[pos]-t2);
				double tmp2=180-(t2-dh[pos-1]);
				if(tmp1>=360) tmp1-=360;if(tmp1<0) tmp1+=360;
				if(tmp2>=360) tmp2-=360;if(tmp2<0) tmp2+=360;
				
				t1=(double)j*6.00+k*0.10;
				t2=t1+180.00;
				if(t2>=360) t2-=360.00;
				pos=upper_bound(dm+1,dm+n+1,t2)-dm;
				double tmp3=180-(dm[pos]-t2);
				double tmp4=180-(t2-dm[pos-1]);
				if(tmp3>=360) tmp3-=360;if(tmp3<0) tmp3+=360;
				if(tmp4>=360) tmp4-=360;if(tmp4<0) tmp4+=360;
				
				tmp1=min(tmp1,360-tmp1);
				tmp2=min(tmp2,360-tmp2);
				tmp3=min(tmp3,360-tmp3);
				tmp4=min(tmp4,360-tmp4);
				maxx=max(max(tmp1,tmp2),max(tmp3,tmp4));
				ans=min(ans,maxx);
			}
		}
	}
	printf("%.6lf\n",ans);
	return 0;
}

标签:dm,noip,dh,double,t2,360,66,模拟,define
来源: https://www.cnblogs.com/WindZR/p/15363331.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有