NOIP 2013 小朋友的数字
来源:互联网 发布:python 频域 编辑:程序博客网 时间:2024/04/27 14:24
【题目链接】点击打开链接
【解题思路】
对于最大子段和问题,我们有O(N)的算法。 具体的做法是这样的:当前要求第I位及之前的最大子段和,如果第(I-1)位及之前的最大子段和大于0,则显然这一位取了也未尝不可(不会减少),也就是当前这一位和前面一段连接起来。否则的话,就新开一段——把前面的最大子段和改成0以后继续往下扫描。 如果一定要说这是DP也可以。
这样朴素的做能得50分, 在计算特征值与分数的过程中记录一下最大值可以的得到80分, 原因在与最后两个点的分数值超过了longlong。
进一步分析可以发现除了第一个小朋友外剩下的小朋友的分数值是不下降的。所以对于一个小朋友他的分数只有两种情况。
1.如果他的前一个小朋友的特征值大于0,那他的分数就为前一个小朋友的分数加上前一个小朋友的特征值。更新当前最大值。
2.如果他的前一个小朋友的特征值小于0,那他的分数就为第二个小朋友的分数。
当一个小朋友的分数值大于1000000000时我们取模
因为第一个小朋友的分数不会大于1000000000,所以我们就可以在计算过程中判断出来是否有小朋友的分数大于第一个小朋友。
这样就可以拿到满分。。
【AC代码】
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define ll long longconst int maxn=1000010;ll n,p,maxsum;ll a[maxn];ll sum[maxn],t[maxn];//前缀和和特征值ll b[maxn];//记录分数int main(){ scanf("%I64d%I64d",&n,&p); for(int i=1; i<=n; i++) scanf("%lld",&a[i]); sum[1]=a[1]; maxsum=a[1]; t[1]=a[1]; for(int i=2; i<=n; i++)//维护前缀和 { sum[i] = max(sum[i-1]+a[i],a[i]); t[i] = max(sum[i],maxsum); maxsum = t[i]; } b[1] = t[1]; b[2] = t[1]+b[1]; bool fuck=false; if(b[2]>=b[1]) { fuck=true; } for(int i=3; i<=n; i++) { if(t[i-1]>0) { b[i]=b[i-1]+t[i-1]; if(b[i]>b[1]) fuck=true; if(b[i]>1e9) b[i]%=p; } else b[i]=b[2]; } ll ans; if(fuck) { ans = b[n]; } else ans = b[1]; ans=ans%p; printf("%lld\n",ans); return 0;}
【参考博客】点击打开链接
0 0
- NOIP 2013 小朋友的数字
- 2013NOIP普级组第三题-- 小朋友的数字(参考洛谷题解)
- 2552: 小朋友的数字
- noip2013小朋友的数字(dp)
- 【noip2013普及】 小朋友的数字
- NOIP2013(3)小朋友的数字
- 洛谷 P1982 小朋友的数字
- 2017.5.5 小朋友的数字 思考记录
- [noip2013]小朋友的数字(dp+规律)
- 小朋友数数字的游戏 java实现算法
- |Tyvj|NOIP2013|动态规划|P3074 小朋友的数字
- [NOIP2013][vijos1850]小朋友的数字(dp+贪心)
- <NOIP> 15 . P1427 小鱼的数字游戏
- NOIP 模拟题 消失的数字
- noip2013 小朋友的数字 (最大子区间和+动态规划)
- Vijos P1850 小朋友的数字(动态规划,最大子段和)
- ◆竞赛题目◆◇NOIP2013普及组◇ 小朋友的数字
- 长大了的小朋友
- 关于linux的目录/etc
- 多线程+网络
- Android官方开发文档Training系列课程中文版:创建自定义View之View的创建
- C++ : :新特性之引用
- 【记录】窗口看门狗
- NOIP 2013 小朋友的数字
- MATLAB中diag函数的作用
- 刚刚写的ORACLE存储过程
- Java线程池基本使用
- 使用Intent方式进行跨进程访问
- Qt5 UI信号、槽自动连接的控件重名大坑
- 表格汇总器(C#)
- Cocos2d-x 内存管理
- 解决List的add方法错使前面的元素被覆盖成相同值