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(计算几何)
没学,待补。