【年前的胡策】训练2.12(贪心)
2018-02-12 21:12
363 查看
题解:
首先显而易见的:填棋子的过程就是划分区间的过程,那么为了框出边界,我们需要在1,n上填好然后就在考场上傻傻的讨论区间的奇偶性,过了样例就跪了大数据,果然不证明的结论都是胡扯。
实际上这道题目有一个结论
f[x]=__builtin_popcount(x)-1
__builtin_popcount(x):x的二进制中有多少个一
怎么跟二进制扯上关系的?
我们可以发现:如果一开始0号位有棋子,为了让1号位的棋子免费,我们需要填上2号位的格子
为了让2号位的棋子免费,我们需要填上4号位的棋子…….
2的幂啊,我们发现这样填的话首先填16的话这一堆都不用管了
因此,我们在相邻的两个棋子之间,只有把棋子放在2的整数幂的位置才能保证答案最小
我们利用倍增的思想,贪心的往空隙中放置相聚尽量远且位置是2的整数幂的棋子(因为这样中间的都不用管了)
代码:
#include <cstdio> #include <algorithm> #define LL long long 4000 using namespace std; int m;LL a[10],n; int work(LL x) { int ans=0; while (x) ans+=(x&1),x>>=1; return ans; } int main() { freopen("chess.in","r",stdin); freopen("chess.out","w",stdout); scanf("%lld%d",&n,&m); if(m==0) { printf("%d",work(n-1)+1); return 0; } bool h1=0,hn=0; for(int i=1;i<=m;i++) { scanf("%lld",&a[i]); if (a[i]==1) h1=1; if (a[i]==n) hn=1; } int ans=0; if (!h1) a[++m]=1,ans++; if (!hn) a[++m]=n,ans++; sort(a+1,a+m+1); for(int i=2;i<=m;i++) ans+=work(a[i]-a[i-1])-1; printf("%d",ans); }
相关文章推荐
- 【loli的胡策】NOIP训练8.10(数论+树形dp+贪心)
- 【loli的胡策】NOIP训练7.20(二分+主席树)
- CSU-ACM2017暑期训练7-模拟&&贪心 A - Radar Installation POJ - 1328
- poj 3465 贪心+优先队列 叉姐的魔法训练
- 【充满原题的胡策】训练2.26 T1(线性基+讲解)
- CSU-ACM2017暑期训练7-模拟&&贪心 F - Sokoban
- 【平安夜的胡策】训练12.24(复数预处理+矩阵快速幂+dp)
- 【充满原题的胡策】训练2.26 T2(三维计算几何)
- HLJU14级贪心训练题解
- <队内胡策> 2017.10.10 (贪心+二分答案+DP)
- 蓝桥杯算法训练——最大最小公倍数(贪心)
- HDU6047 Maximum Sequence(贪心,暑期训练1003)
- 【loli的胡策】训练1.7(hash+记忆化搜索+AC自动机+矩阵优化dp)
- 【学姐的胡策】训练8.17(Lucas+线段树并查集)
- HDOJ贪心训练1006Wooden Sticksd
- 《算法竞赛-训练指南》第二章-2.12_LA 5059
- 【舒老师的胡策】互测3.11(贪心+分块+找规律)
- <队内胡策> 2017.10.24 求逆序对+表达式计算+贪心+Bfs+最短路、exgcd
- 算法训练 Beaver's Calculator/codeforces 207A1 排序+贪心
- HDU 4864Task(多校联合训练1)(贪心)