hdu 4561 (dp做法 || 非dp做法)
题目:
Problem 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组成的元素,元素之间用空格分开。
接下来的T组数据,每组数据第一行输入N,表示数组的元素总个数(1<= N <= 10000)。
再接下来输入N个由0,-2,2组成的元素,元素之间用空格分开。
Output
对于每组数据,先输出Case数。
如果最终的答案小于等于0,直接输出0
否则若答案是2^x ,输出x即可。
每组数据占一行,具体输出格式参见样例。
如果最终的答案小于等于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
非dp做法:
思路: 把0看成隔板,把那一串数分成许多段,之后再计算每一小段里面最多有几个数的连续乘积是整数,再取一个最大值。
代码:
View Code
View Code
1 #include<stdio.h> 2 #include<string.h> 3 int main() 4 { 5 int N; 6 int n,m,i,j,max,flag=0,flag1=0; 7 8 int symbol[10005]; //标记当前位置的数 与之前的连续不为0的数 的乘积 的正负; 9 10 int num[10005]; // 在当前位置对应的数之前(含这个数)共有 多少个 连续的数的乘积大于0; 11 12 scanf("%d",&N); 13 for(j=1;j<=N;j++) 14 { 15 scanf("%d",&n); 16 memset(symbol,0,sizeof(symbol)); 17 memset(num,0,sizeof(num)); 18 symbol[0]=1;flag=0;flag1=0;max=0; 19 for(i=1;i<=n;i++) 20 { 21 scanf("%d",&m); 22 if(m==0) 23 { 24 symbol[i]=1; 25 num[i]=0; 26 flag=0; 27 flag1=0; 28 } 29 else 30 { 31 if(flag1==0) flag1=i; // 记录从一个不为0的数的位置 32 if(m<0) 33 { 34 if(flag==0) flag=i; //记录 这一段不为0的数中 第一个为负值的数的 位置 35 } 36 symbol[i]=symbol[i-1]*m/2; 37 38 if(symbol[i]>0) num[i]=i+1-flag1; 39 else 40 { 41 if(flag==0) num[i]=i+1-flag1; 42 else num[i]=i+1-flag1-num[flag]; 43 } 44 if(num[i]>max&&i>flag) max=num[i]; 45 } 46 } 47 printf("Case #%d: %d\n",j,max); 48 } 49 }
dp 做法:
思路: 负负得正,正正得正 ,正负得负。
dp[1][i]表示 含当前位置的数的 连续乘积为正的数的个数;dp[0][i]表示 含当前位置的数的 连续乘积为负的数的个数
代码:
1 #include<stdio.h> 2 #include<string.h> 3 int main() 4 { 5 int n,N,m,max,i,j; 6 int dp[2][10005]; 7 scanf("%d",&N); 8 for(j=1;j<=N;j++) 9 { 10 max=0; 11 memset(dp,0,sizeof(dp)); 12 scanf("%d",&n); 13 for(i=1;i<=n;i++) 14 { 15 scanf("%d",&m); 16 if(m==0) 17 { 18 dp[0][i]=0; 19 dp[1][i]=0; 20 } 21 else if(m>0) 22 { 23 dp[1][i]=dp[1][i-1]+1; 24 if(dp[0][i-1]) 25 dp[0][i]=dp[0][i-1]+1; 26 } 27 else 28 { 29 dp[0][i]=dp[1][i-1]+1; 30 if(dp[0][i-1]) 31 dp[1][i]=dp[0][i-1]+1; 32 } 33 if(dp[1][i]>max) max=dp[1][i]; 34 } 35 printf("Case #%d: %d\n",j,max); 36 } 37 38 }