ICode9

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

雅礼集训2017day4乱写

2020-04-21 23:06:34  阅读:283  来源: 互联网

标签:ch 2017day4 乱写 pos 雅礼 int define id getchar


day3找不到

t1

先考虑洗涤过程,根据贪心的想法,我们只要每次选择结束时间最早的机器使用就好啦

而且这个过程中每件衣服洗好的时间的一定的,可以记录下来

再考虑烘干,如果我们二分答案,然后用类似的方法记录下来每个被烘干的衣服需要从什么时候开始烘干

那么令洗涤最晚的衣服用烘干最晚的机器,洗涤最早的用烘干最早的,一定是最优的方案

判断一下是否满足所有配对就好了

复杂度\(O(nlog^2n)\)

仔细一想好像根本不用二分,我们直接按照洗涤的方案处理烘干时间,再配对之后取最大值就可以了

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define mid ((l+r)>>1)
#define y1 qwq
#define id(x,y) (((x)-1)*m+(y))
	inline int read()
	{
		int x=0;char ch,f=1;
		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
		if(ch=='-') f=0,ch=getchar();
		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
		return f?x:-x;
	} 
	const int N=1e6+10,inf=1<<30;
	int n,n1,n2,l,r,ret;
	int a[N],b[N];
	int c[N],d[N];
	struct node
	{
		int x,y;
		inline bool operator < (const node &t) const
		{
			return x>t.x;
		}
	};
	priority_queue<node> q1,q2;
	inline void main()
	{
		n=read(),n1=read(),n2=read();
		for(int i=1;i<=n1;++i) a[i]=read(),q1.push((node){a[i],a[i]});
		for(int i=1;i<=n2;++i) b[i]=read(),q2.push((node){b[i],b[i]});
		for(int i=1;i<=n;++i)
		{
			node now=q1.top();q1.pop();
			c[i]=now.x;
			q1.push((node){now.x+now.y,now.y});
			now=q2.top();q2.pop();
			d[i]=now.x;
			q2.push((node){now.x+now.y,now.y});
		}
		for(int i=1;i<=n;++i)
		{
			ret=max(ret,c[i]+d[n-i+1]);
		}
		printf("%lld\n",ret);
	}
}
signed main()
{
	red::main();
	return 0;
}

题外话:写完口胡了一下\(3-n\)个机器的做法:把前两个机器花的时候合并成一个,然后数学归纳

t2写在这里了

t3

看见这个数据范围应该对搜索有信心。。

考虑一下部分分:只要向右走就能安排上的情况

来一个我想不到的\(dp\)状态:\(f[i][j][S]\)表示当前已经完成的信息集合是\(S\),正在处理第\(i\)条信息,已经完成了\(j\)个数字

我们发现有些信息之间存在一定的包含关系

例如两个信息:\(\{1,4,5,6\}\)和\(\{5,1,4,6\}\)

如果我们完成了第一个信息的\(\{1,4\}\),然后继续完成了第二条信息,那么第一条信息也满足了

所以我们可以直接从第一条信息的第\(2\)个数字跳转到第二条信息的第\(0\)个数字

也就是

\(f[1][2][s]->f[2][0][s|(1<<1)]\)

这是一种转移方式,另一种是按部就班地完成当前信息

然后知道这个以后可以记忆化搜索得到答案

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define mid ((l+r)>>1)
#define y1 qwq
#define id(x,y) (((x)-1)*m+(y))
	inline int read()
	{
		int x=0;char ch,f=1;
		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
		if(ch=='-') f=0,ch=getchar();
		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
		return f?x:-x;
	} 
	const int N=1e6+10,inf=0x3f3f3f3f;
	int n,S,ans;
	int a[12][12],s[12],b[12],bit[12];
	bool e[12][12],c[12][12][12];
	bool in[12];
	int f[12][12][2010];
	bool g[12][12][2010];
	inline bool check(int id,int len,int to)
	{
		int pos=0;
		memset(in,0,sizeof(in));
		for(int i=1;i<=len;++i)
			in[a[id][i]]=1;
		for(int i=1;i<=s[to];++i)
		{
			if(in[a[to][i]]) continue;
			b[++pos]=a[to][i];
			in[a[to][i]]=1;
		}
		if(pos!=s[id]-len) return 0;
		for(int i=len+1;i<=s[id];++i)
			if(a[id][i]!=b[i-len]) return 0;
		return 1;
	}
	inline void dfs(int id,int pos,int st)
	{
		if(g[id][pos][st])
		{
			ans=min(ans,f[id][pos][st]);
			return;
		}
		for(int i=1;i<=n;++i)
		{
			if(i!=id&&(bit[i]&st)==0)
				if(c[id][pos][i]&&f[i][0][st|bit[id]]>f[id][pos][st])
				{
					f[i][0][st|bit[id]]=f[id][pos][st];
					dfs(i,0,st|bit[id]);
				}
		}
		if(pos!=s[id]&&f[id][pos+1][st]>f[id][pos][st]+1)
		{
			f[id][pos+1][st]=f[id][pos][st]+1;
			dfs(id,pos+1,st);
		}
	}
	inline void main()
	{
		n=read();S=(1<<n)-1;
		for(int x,i=1;i<=n;++i)
		{
			bit[i]=1<<(i-1);
			while(x=read())
			{
				a[i][++s[i]]=x;
				e[i][x]=1;
			}
		}
		for(int i=1;i<=n;++i)
		{
			for(int j=0;j<=s[i];++j)
			{
				for(int k=1;k<=n;++k)
				{
					c[i][j][k]=check(i,j,k);
				}
			}
		}
		memset(f,0x3f,sizeof(f));
		ans=inf;
		for(int i=1;i<=n;++i) g[i][s[i]][S^bit[i]]=1;
		for(int i=1;i<=n;++i)
		{
			f[i][0][0]=0;
			dfs(i,0,0);
		}
		printf("%d\n",ans==inf?-1:ans);
	}
}
signed main()
{
	red::main();
	return 0;
}

满分算法很相似,只要再加两维表示正在倒序处理第\(k\)条信息,已经处理完成了第\(p\)位

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define mid ((l+r)>>1)
#define y1 qwq
	inline int read()
	{
		int x=0;char ch,f=1;
		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
		if(ch=='-') f=0,ch=getchar();
		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
		return f?x:-x;
	}
	const int N=1e6+10,inf=0x3f3f3f3f;
	int n,S,ans;
	int a[12][12],s[12],bit[12];
	int f[12][12][12][12][1050];
	bool e[12][12][12],c[12][12][12];
	bool in[12];
	bool g[12][12][12][12][1050];
	set<long long> ext;
	inline bool check(int id,int len,int to)
	{
		int pos=0;
		memcpy(in,e[id][len],sizeof(in));
		for(int i=1;i<=s[to];++i)
		{
			if(in[a[to][i]]) continue;
			++pos,in[a[to][i]]=1;
			if(a[to][i]!=a[id][len+pos]) return 0;
		}
		if(pos!=s[id]-len) return 0;
		return 1;
	}
	#define cover(id1,pos1,id2,pos2,st,add) (k=min(dfs(id1,pos1,id2,pos2,st)+add,k))
	inline int dfs(int id1,int pos1,int id2,int pos2,int st)
	{
		if(st==S&&pos1==s[id1]&&!pos2) return 0;
		int &k=f[id1][pos1][id2][pos2][st];
		if(g[id1][pos1][id2][pos2][st]) return k;
		g[id1][pos1][id2][pos2][st]=1;
		if(id2&&!pos2)
		{
			for(int i=0;i<=n;++i)
				if(i!=id1&&!(bit[i]&st))
					for(int j=0;j<=s[i];++j)
						if(c[i][j][id2])
							cover(id1,pos1,i,j,st|bit[i],0);
		}
		for(int i=1;i<=n;++i)
			if(c[id1][pos1][i]&&!(bit[i]&st))
				cover(i,0,id2,pos2,st|bit[i],0);
		if(pos1==s[id1]&&!pos2) return k;
		if(pos1!=s[id1]&&(e[id2][pos2+1][a[id1][pos1+1]]||!id2))
			cover(id1,pos1+1,id2,pos2,st,1);
		if(pos2&&(e[id1][pos1][a[id2][pos2]]||!id1))
			cover(id1,pos1,id2,pos2-1,st,1);
		if(pos1!=s[id1]&&pos2&&a[id2][pos2]==a[id1][pos1+1])
			cover(id1,pos1+1,id2,pos2-1,st,1);
		return k;
	}
	inline void main()
	{
		n=read();
		long long key;
		for(int x,i=1;i<=n;++i)
		{
			s[i]=0,key=0;
			bit[i]=1<<(i-1);
			memset(e[i],0,sizeof(e[i]));x=1;
			while(x)
			{
				x=read();
				key=(key<<1)+(key<<3)+x;
				a[i][++s[i]]=x;
				for(int k=1;k<=s[i];++k)
					if(a[i][k]) e[i][s[i]][a[i][k]]=1;
			}
			--s[i];
			if(ext.count(key)) --i,--n;
			ext.insert(key);
		}
		S=(1<<n)-1;
		for(int i=1;i<=n;++i)
		{
			c[0][0][i]=1;
			for(int j=0;j<=s[i];++j)
			{
				for(int k=1;k<=n;++k)
				{
					c[i][j][k]=check(i,j,k);
				}
			}
		}
		memset(f,0x3f,sizeof(f));
		ans=inf;
		for(int i=1;i<=n;++i)
			ans=min(ans,dfs(0,0,i,s[i],bit[i]));
		printf("%d\n",ans==inf?-1:ans);
	}
}
signed main()
{
	red::main();
	return 0;
}

标签:ch,2017day4,乱写,pos,雅礼,int,define,id,getchar
来源: https://www.cnblogs.com/knife-rose/p/12748654.html

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

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

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

ICode9版权所有