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

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
posted @ 2017-10-07 18:43  让你一生残梦  阅读(131)  评论(0编辑  收藏  举报