【NOIP2012模拟11.1】塔(加强)
2016-08-18 14:58
197 查看
Description
玩完骰子游戏之后,你已经不满足于骰子游戏了,你要玩更高级的游戏。今天你瞄准了下述的好玩的游戏:
首先是主角:塔。你有N座塔一列排开。每座塔各自有高度,有可能相等。
这个游戏就不需要地图了。
你每次可以选择相邻的两座塔合并在一起,即这两座塔的高度叠加后变成了同一座塔。然后原本分别与这两座塔相邻的塔变得与这座新的塔相邻。
你的目标是在使用最少的操作次数在游戏的最后获得一列塔,这些塔的高度从左到右形成一个不下降的数列。
Input
第一行一个整数N。第二行N个整数,从左到右描述塔的高度Ai。
Output
仅一个整数表示最少的操作次数。Sample Input
58 2 7 3 1
Sample Output
3Data Constraint
n<=106Solution
这个加强很不好玩首先看看不加强的数据范围:n<=3000
那么显然是暴力
设f[i]表示合法到点i的最小步数
g[i]表示在f[i]状态时i这个点的最小高度
当g[j−1]<=sum[i]−sum[j−1]时
f[i]=min(f[j−1]+i−j)
十分显然
考虑优化
为了使步数最少,那一定要使块的数量最多,那每个块的大小就要最小
也就是说只要有一个最大的j满足条件,就可以直接转移然后break
90分了!!!
如果你RP够好,加个读入优化也应该能过
如果RP不够好,那就只能打单调队列或二分法优化了
Code
#include<cstdio> #include<algorithm> #include<cstring> #define fo(i,a,b) for(int i=a;i<=b;i++) #define N 1001000 #define ll long long using namespace std; int n,t,y; ll a ,f ,h ,s ,d ; int main() { scanf("%d",&n);s[0]=0; fo(i,1,n) scanf("%lld",&a[i]),s[i]=s[i-1]+a[i]; d[t=y=1]=0; fo(i,1,n) { while(h[d[t+1]]+s[d[t+1]]<=s[i]&&t<y) t++; f[i]=f[d[t]]+i-d[t]-1;h[i]=s[i]-s[d[t]]; while(t<=y&&h[d[y]]+s[d[y]]>=h[i]+s[i]) y--; d[++y]=i; } printf("%lld",f ); }
相关文章推荐
- 【NOIP2012模拟11.1】塔(加强)
- JZOJ3083. 【NOIP2012模拟11.1】塔(加强)
- jzoj3083. 【NOIP2012模拟11.1】塔(加强)
- 【NOIP2012模拟11.1】骰子游戏
- JZOJ3082. 【NOIP2012模拟11.1】骰子游戏
- jzoj3082. 【NOIP2012模拟11.1】骰子游戏
- {题解}[jzoj3083]【NOIP2012模拟11.1】塔
- jzoj3053. 【NOIP2012模拟10.25】旅行 (Standard IO)
- 高中OJ3012. 【NOIP2012模拟10.6】购买
- 【模拟】[NOIP2012]Vigenère密码
- NOIP2012 开车旅行 倍增与模拟结合后的调试神题
- 【NOIP2012模拟11.6】背包问题
- jzoj 3076. 【备战NOIP2012图论专项模拟试题】位图
- JZOJ3052. 【NOIP2012模拟10.25】剪草
- noip2012 寻宝 (模拟)
- 【NOIP2012模拟10.29】排列 一题总结
- NOIP2012普及组 T3 摆花(加强版)
- JZOJ【3072】【NOIP2012模拟10.31】掷骰子
- [JZOJ5442]【NOIP2017提高A组冲刺11.1】荒诞([BZOJ3060]【POI2012】Tour de Byteotia)
- 【NOIP2012模拟11.8】斐波那契