hdu 4561 模拟小题or连续最大积

来源:互联网 发布:园林设计手机教学软件 编辑:程序博客网 时间:2024/06/07 20:58

Description

小明和他的好朋友小西在玩一个游戏,由电脑随机生成一个由-2,0,2三个数组成的数组,并且约定,谁先算出这个数组中某一段连续元素的积的最大值,就算谁赢!

比如我们有如下随机数组:

2 2 0 -2 0 2 2 -2 -2 0

在这个数组的众多连续子序列中,2 2 -2 -2这个连续子序列的积为最大。

现在小明请你帮忙算出这个最大值。

Input

第一行输入一个正整数T,表示总共有T组数据(T <= 200)。

接下来的T组数据,每组数据第一行输入N,表示数组的元素总个数(1<= N <= 10000)。

再接下来输入N个由0,-2,2组成的元素,元素之间用空格分开。

Output

对于每组数据,先输出Case数。

如果最终的答案小于等于0,直接输出0

否则若答案是2^x ,输出x即可。

每组数据占一行,具体输出格式参见样例。

Sample Input

2
2
-2 0
10
2 2 0 -2 0 2 2 -2 -2 0

Sample Output

Case #1: 0
Case #2: 4


刚开始的思路就是搜索吧,搜索主要就是三点,一点就是这点是2,那么直接搜索,一点就是-2,那么就要考虑要与不要。就可以了。

  不过就是超时间了,具体代码如下:

超时代码:

#include<iostream>#include<iomanip>#include<cmath>#include<stdio.h>using namespace std;int vis[10005],ans,n;void dfs(int flag,int num,int i){    ///结束条件    if(i==n+1) return ; //   printf("%d\n",num);    ///取最大值    if(flag==1 && ans<num)    {        ans = num;    }    ///重置条件    if(vis[i]==0)        dfs(1,0,i+1);    else    {        //printf("%d\n",i);        ///取不取的条件        if(vis[i]==-2)        {            int k = flag;            if(flag) flag=0;            else flag = 1;            dfs(flag,num+1,i+1);            flag = k;            dfs(1,0,i+1);        }        else            dfs(flag,num+1,i+1);    }    return ;}int main(){    int T;    int l=1;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=1; i<=n; i++)            scanf("%d",&vis[i]);        ans=0;        dfs(1,0,1);        printf("Case #%d: %d\n",l++,ans);    }    return 0;}
然后就是找原因,找原因了。


题目主要就是以0为分割点,具体代码见。

代码如下:

#include<iostream>#include<iomanip>#include<cmath>#include<stdio.h>using namespace std;int vis[10005],ans,n;int solve(int s,int e){    ///st,ed分别表示开始第一个-2的位置和最后一个-2的位置    ///cnt表示-2的数量    int st,ed,cnt,flag=1;    cnt =0;    int mid =0;    if(s==n+1) return 0;    for(int i=s;i<e;i++)    {        if(vis[i]==-2){            cnt++;            if(flag==1){                flag=0;                st = i;            }            ed = i;        }    }    if(cnt%2==0) return e-s;    else{        ///分为四段s到st,s到ed,st到e,ed到e,num去取三段最大值        if(st-s>mid) mid = st - s;        if(ed-s>mid) mid = ed - s;        if(e-st-1>mid) mid = e - st-1;        if(e-ed-1>mid) mid = e - ed-1;        return mid;    }}int main(){    int T;    int l=1;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=1; i<=n; i++)            scanf("%d",&vis[i]);        ans=0;        vis[0]=0;        for(int i=0;i<=n;)        {            if(vis[i]==0)            {                int st = i+1;                while(true){                    i++;                    if(i==n+1 || vis[i]==0){                        int mid = solve(st,i);                        if(ans<mid) ans = mid;                        break;                    }                }            }        }        printf("Case #%d: %d\n",l++,ans);    }    return 0;}

正确代码转载地址:http://blog.csdn.net/hnust_xiehonghao/article/details/9280839

原创粉丝点击