AtCoder Beginner Contest 251

AtCoder Beginner Contest 251

D

给定一个1e6范围内的数n,要你构造出一个数组,对于1~n中的任何一个数都能用数组中最多三个数的和加起来。
这题真的是很好的一道思维题,想了我两个小时都没想出来

代码

int n,m,c;
int a[N],cnt=0;
//我真shabi啊
//分三组就行了,1e6 ,那每两个10进制位为1组就ok了。
//n没用
void solve() 
{
	cin>>n;
	for(int num=1;num<=10000;num*=100)
	{
		for(int i=1;i<=99;i++) a[++cnt]=num*i;
	}
	cout<<cnt<<endl;
	for(int i=1;i<=cnt;i++) cout<<a[i]<<" ";
}

E

题意

n只牛,对于每头牛i,喂养一次的费用为cost[i],连带着下一头一起喂,也就是说,花费cost[i]可以喂养第i头牛和第i+1头牛。第n头牛的下一位是1.
问最少花多少钱才能让每头牛至少喂养一次。

思路

简单dp,令\(f[i][0]\)表示当前牛是由上一头牛的喂养连带的,\(f[i][1]\)表示喂养当前牛。
环怎么处理?我们可以假定两种情况,一种是第1头牛喂养是不用花钱的(即第n头牛一定要喂养),另一种是要花钱的。

代码

void solve() 
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	f[1][0]=a[n],f[1][1]=a[1];//第1头是连带的
	for(int i=2;i<=n;i++) 
	{
		f[i][0]=f[i-1][1];
		f[i][1]=min(f[i-1][0],f[i-1][1])+a[i];
	}
	int ans=min(f[n][0],f[n][1]);
	f[1][0]=0,f[1][1]=a[1];//不是连带的
	for(int i=2;i<=n;i++) 
	{
		f[i][0]=f[i-1][1];
		f[i][1]=min(f[i-1][0],f[i-1][1])+a[i];
	}
	ans=min(ans,f[n][1]);
	cout<<ans<<endl;
}

F

题意

在一个简单图中,找两棵树(n个结点)(以1为根节点),第一个棵树要满足 除这棵树外的边,它的两个端点在树中 的关系是一个是另一个的祖先。
第二棵树要满足 除这棵树外的边,它的两个端点在树中的关系并非一个是另一个的祖先。

思路

第一个显然是dfs,这样的话除这棵树外的边一定有一个点是在树内另一个在树外。
第二个就是bfs了,假设a和b之间有一条边,那它们肯定有一个共同的祖先,否则就不满足条件了。

代码

自己写。

G(计算几何)

没学,待补。

posted @ 2023-03-02 19:04  Liang2003  阅读(10)  评论(0编辑  收藏  举报