举个例子:9 -18 3 2 7 1在求这串维数组(连续)区间的最大值的时候,最开始的想法就是暴力,把每个区间的数都加在一起,然后再比较出最大的数,这种方法虽然可以做出来,但是太浪费时间了,所以就有了一个比较简单的想法动态规划的思想。先整一段代码瞅瞅:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int main(){
int n;
int a[100];
while(~scanf("%d", &n)){
int i, sum = 0;//sum用来记录某个区间的和
for(i = 0; i < n; i++){
cin>>a[i];
}
int max1 = 0;//如果区间全为负的情况下,使max1 = -999999,因为当全为负的情况下
//更新的结果是最大的负数
for(i = 0; i < n; i++){
sum += a[i];
max1 = max(sum, max1);//max1进行更新最大值,用max1来记录该点出现过的最大值。
if(sum < 0)sum = 0;//如果该位置小于0的话,那就重新开始,
//这个语句最好放在句尾,如果全为负,这么才能更新到最大的负数
}
cout<<max1<<endl;
}
return 0;
}
//9 -18 3 2 7 1
//最快开始max1 = 0,然后sum = 9 > 0 max1 更新为 9
//sum = -9 < 0,sum 设置为0,max1不进行更新还是 9;
//sum= 3 > 0, sum < max1,max1不进行更新还是 9;
//sum = 5 > 0, sum < max1; max1不进行更新还是 9;
//sum = 12 > 0; sum > max1; max1进行更新更新为 12;
//sum = 13 > 0; sum > max1; max1进行更新更新为 13;
//最后输出max1,max1就是区间最大值
动态规划的思想就是从头开始累加,如果结果小于0,就把记录累加结果的值置为0,与此同时用一个数记录出现的最大结果,这个就是动态规划的思想了。下面是一道例题:
Problem 2253 Salty Fish
链接:http://acm.fzu.edu.cn/problem.php?pid=2253
这题就是咸鱼翻身,意思就是在某一区间对区间是0的数给翻过来,只能一次,求出最后有几条咸鱼翻身。
这题的想法就是先统计出有多少条鱼已经翻身了,然后把1置为-1,把0置为1,求出这个数组区间的最大值,也就是之前讲的思想,加上之前的和,就是结果。为什么这么做就可以了,因为你想把0置为1,但是你之前有的1,你是不想动的,但是你只要动了,你最原始的1,就相当于减少了,所以是-1,0置为1,相当于之前的数增加了。
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int a[100001], b[100001];
int main(){
int n, i;
while(~scanf("%d", &n)){
int sum = 0;
for(i = 0; i < n; i++){
scanf("%d", &a[i]);
if(a[i] == 1)b[i] = -1;
else b[i] = 1;
sum += a[i];
}
if(sum == n)
{
printf("%d\n",n-1);
continue;
}//至少翻转一条鱼,所以当全为1的时候总数减1
int max1 = 0, c = 0;
for(i = 0; i < n; i++){//连续区间求最大的值;
c += b[i];
if(c < 0)c = 0;
max1 = max(c, max1);
}
printf("%d\n",max1+sum);
}
return 0;
}