NOIP真题做题经历——MLE之内存计算

noip中,试题会有程序运行内存上限(MLE),这个内存上限指的是什么,怎样才能知道自己程序的运行内存?

下面就让我这个今天上午刚刚MLE的鸡来分析一下。

 内存上限就是指程序运行时消耗的内存。
如果你声明的是静态的(数组、普通变量等),那内存计算就是单位数*每个单位所用的字节数之和。(动态的东西,我们这里不做研究)

#define ll long long 
ll a[400000] ;
定义

我们定义了一个ll类型的a数组。
一个ll占8个字节,那么这个数组就占了400000 * 8 = 3200000B = 3125KB 
依次这么算下去,就可以粗略的估计自己占了多少内存了。

那么问题来了,自己的程序要占多少内存才不会MLE呢?
假如程序要求是128M。那么我们大约留出来10到15MB的内存(供代码的字使用吗,再一个可以防止意外得发生),剩下的110多给变量使用就比较稳妥了。

下面给出各种变量占内存多少的数据以及各个单位的换算关系。

    数据大小          换算关系

事实上我们不需要如同上述那样,开到110MB内存的样子。
  举个栗子来说吧。

补天计划(fence.cpp  我就笑笑——谷链

就这个题啊——补天计划。我对这个题很无语的,这个题我就MLE了。
  不得不抱怨的是,你会看到这个题根本就没写内存限制是多少。

那么,再来看一下我的代码

 1 #include<iostream>
 2 #include<cmath>
 3 using namespace std;
 4 int du[10050] ={0}, ola[10050] ={0}, n , start  = 0,
 5     map[1050][1050] ={0}, m = 0 , tot = 0;
 6 void dfs(int k){
 7     for(int i = 1 ; i <= m ; i++){
 8         if(map[k][i] != 0){
 9             map[k][i] --;
10             map[i][k] --;
11             dfs(i);
12         }
13     }
14     tot++;
15     ola[tot] = k;
16 }
17 
18 int main(){
19     freopen("fence.in" , "r" , stdin);
20     freopen("fence.out" , "w" , stdout);
21     int x , y;
22     cin >> n;
23     for(int i = 1 ; i <= n ; i++){
24         cin >> x >> y;
25         map[x][y] ++;
26         map[y][x] ++;
27         du[x] ++;
28         du[y] ++;
29         m = max(x , m);
30         m = max(m , y);
31     }
32     for(int i = 1 ; i <= m ; i ++) {
33            if(du[i] % 2 == 1){
34                start = i;
35                break;
36            }
37     }
38     if(start == 0){
39         for(int i = 1 ; i <= m ; i ++){
40             if(du[i] > 0){
41                 start = i;
42                 break;
43             }
44         }
45     }
46     dfs(start);
47     for(int i = tot ; i >= 1 ; i--){
48         if(ola[i] > 500)
49         ola[i] %= 500;
50         cout << ola[i] << endl;
51     }
52     return 0;
53 }
补天

(10050 + 10050 + 1050 * 1050) * 8 = 8980800B = 8770.3125KB ≈ 8.6MB

加上代码什么乱七八糟的能占用15MB不得了了(这么小的内存占用也会爆?)

算了,抱怨先不提,回归正题吧。
  定义变量的时候最好能定义  数据范围  的最大值+10到20(防止溢出)这个题我后来改成了定义550*550的二维数组就没有MLE。

另外加一个提示:如果最后两个点数据较大,你没有绝对能做对的方法,而且你还面临着MLE的危险,你到不如就弄到小一点的数据,防止最大化数据结果全部MLE,你内存弄小点得80分和你冒险得0分差别是无限大的。

刚刚有个大佬给出了简便的方法,选中的就是内存大小(B做单位)

这个使用要有前提的(加一些乱七八糟的东西需要配置好G++才行——方法详见另一篇博客【链】

以上两种方法都可以算内存,第二种不会就第一种吧(第二种很显然更科学,不会也无所谓),第一个必须要估计的多一些才行。比直接计算的多留出5到10MB就OK了。

 

总结结束。采用以上两个方法就能大大减小MLE的几率了。

posted @ 2017-06-11 15:57  秦时、长浩  阅读(1251)  评论(2编辑  收藏  举报