洛谷P2545 [AHOI2004]实验基地

news/2024/11/16 0:58:34/

题目描述

 

输入输出格式

输入格式:

 

第一行有一个整数N(3<N<2000),表示登陆地带的大小是2×N。随后的两行每一行有N个整数(其绝对值不超过10^6),表示对应的矩形土地的适用度评估值,各个整数之间用一个空格隔开。

 

输出格式:

 

只有一行输出,为整数M,即所确定的实验基地的适用度。

 

输入输出样例

输入样例#1: 

4
-1 2 -3 4
5 6 7 8

输出样例#1: 

31

这一题中n<=2000 所以可以想到O(N^2)

这一题的意思是在2*n的矩阵中找出权值和最大的U型,因为有负数,所以我们要找出最小的子段和

那么怎么求这个值呢?

我们可以定义一个s,不断的加当前位置的数,如果s的值变为是正数,那么肯定不是最有的,所以s重置为0

反之如果当前是数正数,不一定要断开这一段累加,因为s可能还是负数,如果后面也有负数,就对后面会有帮助

因此只有当s>0 的时候把s变为0

并且定义一个minn记录当前搜索的s的最小值,因为当前的s不一定是最优的,也没有必要用当前的s

如果看不懂这一段文字,那么代码一定能够帮助您

#include <iostream>using namespace std ;const int N = 2e3 + 10 ;int n , a[N][2] ; 
int ans = -999999999 ; //ans记录全局最优解 int main() {cin >> n ;for ( int i = 1 ; i <= n ; i ++ ) cin >> a[i][0] ; //输入 for ( int i = 1 ; i <= n ; i ++ ) cin >> a[i][1] ;for ( int i = 1 ; i <= n - 2 ; i ++ ) {int now , minn = 0, s = 0 ; //min记录最小的s,now表示当前所有的和 now = a[i][0] + a[i][1] + a[i+1][0] + a[i+1][1] ;for ( int j = i + 2 ; j <= n ; j ++ ) {s += ( a[j-1][0] ) ; s = min ( s , 0 ) ; //累加,如果超过0就变为0 minn = min ( minn , s ) ; //记录最小值 now += a[j][0] + a[j][1] ; //累加一下 ans = max ( ans , now - minn ) ; //记录最大值 }}cout << ans << endl ; //输出 return 0 ;
}

然而这不是最快的,其实还有一个O(n)的做法,即使n有几千万都不怕(记得加快读,cin中看不中用)

我们定义5个状态 :

  1. 该列不选且之前未建过实验基地。
  2. 该列不选且之前已经建完实验基地。
  3. 该列全选且未建过样品采集区。
  4. 该列全选且已建过样品采集区。
  5. 该列选下面一行(上面建样品采集区)
     

状态继承也很简单:

dp[i][1] = dp[i-1][1] ;
dp[i][2] = max ( dp[i-1][2] , dp[i-1][4] ) ;
dp[i][3] = max ( dp[i-1][1] , dp[i-1][3] ) + a[i][0] + a[i][1] ;
dp[i][4] = max ( dp[i-1][4] , dp[i-1][5] ) + a[i][0] + a[i][1] ;
dp[i][5] = max ( dp[i-1][3] , dp[i-1][5] ) + a[i][1] ;

这个继承是很好看懂的,我就不多说了,上一个代码(加滚动数组优化)

#include <iostream>using namespace std ;const int N = 2e3 + 10 ;int n , a[N][2] ; 
int dp[2][7] ;  int main() {cin >> n ; for ( int i = 1 ; i <= n ; i ++ ) cin >> a[i][0] ;for ( int i = 1 ; i <= n ; i ++ ) cin >> a[i][1] ;dp[1][1] = 0 ; dp[1][3] = a[1][0] + a[1][1] ;dp[1][2] = dp[1][4] = dp[1][5] = -999999999 ;for ( int i = 2 ; i <= n ; i ++ ) {dp[i&1][1] = dp[i&1^1][1] ;dp[i&1][2] = max ( dp[i&1^1][2] , dp[i&1^1][4] ) ;dp[i&1][3] = max ( dp[i&1^1][1] , dp[i&1^1][3] ) + a[i][0] + a[i][1] ;dp[i&1][4] = max ( dp[i&1^1][4] , dp[i&1^1][5] ) + a[i][0] + a[i][1] ;dp[i&1][5] = max ( dp[i&1^1][3] , dp[i&1^1][5] ) + a[i][1] ;}cout << max ( dp[n&1][2] , dp[n&1][4] ) << endl ;return 0 ;
}

给大家留一个问题:

请问为什么O(N^2)代码比O(N)的代码快?快在何处?


http://www.ppmy.cn/news/303973.html

相关文章

警惕利用CVE-2015-2545漏洞进行针对性攻击

2015年末&#xff0c;卡巴斯基实验室的全球研究和分析团队&#xff08;GReAT&#xff09;对未来的威胁环境趋势变化进行了一系列预测。其中一个关键趋势是针对性攻击将变得更为简单和高性价比。包括使用&#xff08;循环使用&#xff09;现成的恶意软件、合法的免费软件或商业软…

zoj 2545

说的是随着计算机的发站。处理器的位数也在不断增加。。10年增加一倍。。现在给你了一种判断增长等级的办法&#xff0c;&#xff0c;让你用这种办法来判断这个数。。其实就是如果这个计算机的位数是32位那么找出一个n是n&#xff01;小于2的32次方。其实可以把所有的都求出来之…

POJ 2545 解题报告

这道题和之前的2247&#xff0c; 1338是一样的。唯一注意的地方是数据范围更大&#xff0c;不能用int了&#xff0c;用unsigned long long即可。 thestoryofsnow2545Accepted160K0MSC879B /* ID: thestor1 LANG: C TASK: poj2545 */ #include <iostream> #include &…

hdu2545树上战争

树上战争 Time Limit : 10000/4000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 4 Accepted Submission(s) : 4 Problem Description 给一棵树&#xff0c;如果树上的某个节点被某个人占据&#xff0c;则它的所有儿子都被占据&#xf…

ZOJ-2545

也比较简单&#xff0c;转化为对数计算就行了 #include<stdio.h> #include<math.h>int main() {int i, a[23], n 1;double sum 0, log2 log(2);for (i 2; i < 22; i){int max 1 << i;while (sum / log2 < max)sum log(n);a[i] n - 2;}while (sc…

2545 ACM 博客 比较树的路径长短

题目&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid2545 题意&#xff1a;比较树的路径长短 思路&#xff1a;利用数组存入父节点的值&#xff0c; 例如&#xff1a; 5 2 1 2 1 3 3 4 3 5 4 2 查找 4 进行了 3 4和1 3 两步&#xff0c;如何判断到达了根节点…

POJ 2545

还是一样的题&#xff0c;&#xff0c;&#xff0c;不解释。不过数据真的太弱了&#xff0c;竟然可以0ms过&#xff0c;&#xff0c;&#xff0c;&#xff0c;看来今天真的很水。。。。。。题目&#xff1a; Hamming Problem Time Limit: 1000MS Memory Limit: 65536KTotal Sub…

POJ 2545 Hamming Problem 笔记

3个素数p1、p2、p3。汉明序列中的元素都是由这3个素数相乘得来&#xff0c;并按增序排列。求汉明序列的第 i 个元素。