一些常见的优化:读入优化,滚动数组

1.读入优化

我们平时所使用的scanf,cin速度都较慢,当读入的数据达到10^5规模以上时,就会开始显现劣势 而c中自带的getchar函数读入速度较快,可以用来优化数字的读入速度。

 1 inline int get_num()
 2 {
 3 int num = 0;
 4 char c;
 5 bool flag = false;
 6 while ((c = getchar()) == ‘ ‘ || c == ‘\n‘ || c == ‘\r‘);
 7 if (c == ‘-‘) flag = true;
 8 else num = c - ‘0‘;
 9 while (isdigit(c = getchar()))
10 num = num * 10 + c - ‘0‘;
11 return (flag ? -1 : 1) * num;
12 }
 1 inline int read()
 2 {
 3     int ff=1,ret=0;
 4     char s;
 5     s=getchar();
 6     while(s<‘0‘||s>‘9‘)
 7     {
 8         if(s==‘-‘) ff=-1;
 9         s=getchar();
10     }
11     while(s>=‘0‘&&s<=‘9‘)
12     {
13         ret=ret*10+s-‘0‘;
14         s=getchar();
15     }
16     return ret;
17 }

2.滚动数组

写Dp经常需要大家开高维数组,比如F[t][i][j]。有的时候转移仅需要上一维数组,如F[t-1][i][j],而F[t-2],F[t-3]都不再有用,留着占用大量空间。我们可以用滚动数组的方式节省大量空间。 本来:int F[100][100][100]; 滚动:int F[2][100][100];

使用姿势: 维护两个数字指针Now和Pre,分别表示当前在哪一维,上一维在哪一维。也就是0和1这两个下标,哪个表示的是F[t][i][j],哪个表示的是F[t-1][i][j]。

1 //例子:
2 for (int t = 1; t <= T; t++)
3 {
4    swap(Now, Pre);/*注意这个swap用的非常精妙,不用把两个数组的值互换,仅仅互换指针就可以了。*/
5    for (int i = 1; i <= N; i++)
6        for (int j = 1; j <= M; j++)
7             F[Now][i][j] = F[Pre][i…][j…] + …;
8 }
时间: 2024-10-08 22:51:55

一些常见的优化:读入优化,滚动数组的相关文章

POJ 1159 回文LCS滚动数组优化

详细解题报告可以看这个PPT 这题如果是直接开int 5000 * 5000  的空间肯定会MLE,优化方法是采用滚动数组. 原LCS转移方程 : dp[i][j] = dp[i - 1][j] + dp[i][j -1] 因为 dp[i][j] 只依赖于 dp[i - 1][j] 和 dp[i][j - 1] 所以可以采用滚动数组如下: dp[i % 2][j] = dp[(i - 1) % 2][j] + dp[i % 2][j - 1] 可以实现节省空间的方法 答案存储在 dp[n % 2

HDU - 1024 Max Sum Plus Plus 滚动数组优化

给定n个数字,求其中m段的最大值(段与段之间不用连续,但是一段中要连续) 例如:2 5 1 -2 2 3 -1五个数字中选2个,选择1和2 3这两段. dp[i][j]从前j个数字中选择i段,然后根据第j个数字是否独立成一段,可以写出 状态转移方程:dp[i][j]=max(dp[i][j-1]+num[j],max(dp[i-1][k])+num[j]) 这里的max(dp[i-1][k])代表的拥有i-1段时的最大值,然后再加上num[j]独立成的一段. 但是题目中没有给出m的取值范围,有可

HDU - 1024 Max Sum Plus Plus(dp+滚动数组优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024 题意:给定n个数字,求其中m段的最大值(段与段之间不用连续,但是一段中要连续) 例如:2 5 1 -2 2 3 -1五个数字中选2个,选择1和2 3这两段. 题解:dp[i][j]从前j个数字中选择i段,然后根据第j个数字是否独立成一段,可以写出 状态转移方程:dp[i][j]=max(dp[i][j-1]+num[j],max(dp[i-1][k])+num[j]) 这里的max(dp[i-

Codeforces 712 D. Memory and Scores (DP+滚动数组+前缀和优化)

题目链接:http://codeforces.com/contest/712/problem/D A初始有一个分数a,B初始有一个分数b,有t轮比赛,每次比赛都可以取[-k, k]之间的数,问你最后A比B大的情况有多少种. dpA[i][j]表示第i轮获得j分的情况数.因为第i轮只和第i-1轮有关,所以这里i用滚动数组优化. 要是普通做法3个for就会超时,所以要用前缀和优化,dpA[i][j]可以由一段连续的dp[i - 1][x]转移过来,所以用sumA数组存取dp[i - 1][x]的前缀

POJ 1159 滚动数组优化内存

题意: 输入一个n和长度为n的字符串,求最少需要增加多少个字符,使之成为一个回文(从左到右读和从右到左读是一样的)   (其实就是括号配对的变形) 知识点: 滚动数组内存优化.就像dp[5005][5005] ,占用的内存太大 ,无法编译,利用滚动数组就能很好的解决这个问题,简单来说就是dp[3][5005]来代替dp[5005][5005] ,用dp[i%3][j],dp[(i-1)%3][j], dp[(i+1)%3][j]表示.(其实这一题还可以这样改:用short int dp[5005

一道简单的递推题(快速幂+矩阵乘法优化+滚动数组)

问题 F: 一道简单的递推题 时间限制: 1 Sec  内存限制: 128 MB提交: 546  解决: 48[提交][状态][讨论版] 题目描述 存在如下递推式: F(n+1)=A1*F(n)+A2*F(n-1)+...+An*F(1) 求第K项的值对1000000007取模的结果 输入 单组测试数据 第一行输入两个整数 n , k (1<=n<=100,n<k<=10000000000) 第二行输入 n 个整数 F(1)   F(2)   ...   F(n) 第三行输入 n

01 背包基础 - 空间优化 (滚动数组,一维阵列)

2017-09-03 11:39:16 writer:pprp 以很简单的一个动态规划问题为引入: 从左上角到右下角走过的路径和最大,问你最大为多少? 1.可以想到普通的dp 状态转移为: dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + arr[i][j]; 2.采用滚动数组的方式-节约了不必要的空间 状态转移为:dp2[i%2][j] = max(dp2[(i+1)%2][j],dp2[i%2][j-1]) + arr[i][j]; 3.采用一维阵列的方式更加节

P5241 序列(滚动数组+前缀和优化dp)

P5241 序列 挺神仙的一题 看看除了dp好像没什么其他办法了 想着怎么构个具体的图出来,然鹅不太现实. 于是我们想办法用几个参数来表示dp数组 加了几条边肯定要的吧,于是加个参数$i$表示已加了$i$条边 这显然是不够的.于是我们又想:强连通分量.....连通块....... 于是加个$j$表示还有$j$个强连通分量 于是dp数组为$f[i][j]$ 这是我们发现一个问题,状态$f[i][j]$不一定是合法的. 那dp不就GG了吗 再次撕烤,我们发现每次加上的边无非就3种情况: 1.把2个强

字符串匹配dp+bitset,滚动数组优化——hdu5745(经典)

bitset的经典优化,即把可行性01数组的转移代价降低 bitset的适用情况,当内层状态只和外层状态的上一个状态相关,并且内层状态的相关距离是一个固定的数,可用bitset,换言之,能用滚动数组是能用bitset优化的前提 /* dp[i,j][0|1|2]表示p串的第i位,s串的第j位相匹配,pi和pi-1换,pi不换,pi和pi+1换的状态下是否能匹配 dp[i,j][0] = dp[i-1,j-1][2] & p[i-1]==s[j] dp[i,j][1] = (dp[i-1,j-1]